??xml version="1.0" encoding="utf-8" standalone="yes"?>
mysql数据q移?span>oracleQ其中有个表名叫“bil_vip”Q有10万条记录Q迁Ud查发现oracle数据库只插入34464条记录,E序执行q程没有发现M错误。修Ҏ据库q接代码向mysql插入10万条记录Q结果都插入OK?/span>
扚w插入使用spring jdbctemplate.batchUpdate(sql, new BatchPreparedStatementSetter());ҎQ该Ҏ的核心是PreparedStatement?strong style="font-weight: bold">executeBatchҎ?/span>
2. l箋实验Q?/strong>
新徏一?span>Test表,只有一个name字段做实验?/span>
抛弃jdbctemplateQ直接用PreparedStatement做实验,l果和jdbcTemplate是一LQ实验证明L会丢?5536条记录?/span>
oracle 驱动的问题?换了最?span>driverQ还是不行。l探?...
3. 希望之光Q?/strong>
早上发了个消息向大家征求思\Q中说了一句分批处理,点亮了我的思\。按照中提供思\Q每1万条记录一批,分多批发送给Oracle?/span>
l果喜出望外Q?span>10万条记录全部插入成功。但?65536"q个数字是什么意思呢......
在网上搜索文章发玎ͼq个65536是一个bug。当PreparedStatement扚w处理正好65536个记录时候,E序会挂?/span>。我试了一下真的挂MQ太吓h了,q坑够深的?/span>
4. 解决ҎQ?/strong>
spring jdbctemplateq是很好用的Q而且业务已经被我装了,如果使用PreparedStatement意味着多了一个处理分支,以后l护会很ȝ?/span>
我新Z?span>MyJdbcTemplatec,l承 jdbctemplatec,q覆盖了batchUpdateҎ。这下舒服了Q系l又恢复了整z?span>
5. ★ l论和收P
ü 有事多思考,多请教n边同事?/span>
ü 坚持Open-close原则(Open for extension, Closed for modification)会系l更好的扩展Q非常容易维护,关键是要坚持q个原则Q如果我因ؓ一个特D分支用了PreparedStatementQ这样势必破坏了q个原则Q日后的l护必然会很ȝ?/span>
ü Zoracle数据如果使用jdbc扚wQ一定要分批发送数据oracleQ否则正好发一?5536pȝ挂死,大于65536数据׃失,杯具呀......
6. 题目何以?#8220;血?#8221;Q?/span>
周二打球回家想q个问题Q打开W记本调试,不知不觉搞到很晚Q媄响媳妇睡觉(媛_早上5:30上班Q,被痛骂一,赶紧上床睡觉Q我媛_气的不行Q手痛砸了一下床板(我们的床撤掉了床垫,只有床架和木板)Q床一下子塌了Q把媛_吓坏了,把我腿弄伤了一块,唉,“血?/span>”呀?/span>
一?span lang="EN-US"> 概念
Commons-logging : apache最早提供的日志的门面接口。避免和具体的日志方案直接耦合。类gJDBC ?span lang="EN-US">api 接口Q具体的?span lang="EN-US">JDBC driver 实现由各数据库提供商实现。通过l一接口解耦,不过其内部也实现了一些简单日志方案?/span>
Log4j : l典的一U日志解x案。内部把日志pȝ抽象装?span lang="EN-US">Logger ?span lang="EN-US">appender ?span lang="EN-US">pattern {实现。我们可以通过配置文gL的实现日志系l的理和多样化配置?
Slf4j : 全称?span lang="EN-US">Simple Logging Facade for JAVAQ?span lang="EN-US">java单日志门面。是对不同日志框架提供的一个门面封装。可以在部v的时候不修改M配置卛_接入一U日志实现方案。和commons-loging 应该有一L初衷。个人感觉设从计上更好一些,没有commons 那么多潜规则。同时有两个额外特点Q?
1. 能支持多个参敎ͼq过{} 占位W进行替换,避免老写logger.isXXXEnabled q种无奈的判断,带来性能提升见:http://www.slf4j.org/faq.html#logging_performance ?
2.OSGI 机制更好兼容支持
一图胜千言Q官|上的一个图Q?br />
从上囑֏以发玎ͼ选择q是很多的?
Logback : LOGBack 作ؓ一个通用可靠、快速灵zȝ日志框架Q将作ؓLog4j 的替代和SLF4J l成新的日志pȝ的完整实现。官|上U具有极佳的性能Q在关键路径上执行速度是log4j ?0 倍,且内存消耗更。具体优势见Q?
http://logback.qos.ch/reasonsToSwitch.html
二? 常见日志Ҏ和注意事?
1.Commons-logging+log4j : l典的一个日志实现方案。出现在各种框架里。如spring 、webx 、ibatis {等。直接用log4j 卛_满我们的日志方案。但是一般ؓ了避免直接依赖具体的日志实现Q一般都是结合commons-logging 来实现。常见代码如下:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
private static Log logger = LogFactory.getLog(CommonsLoggingTest.class);
代码上,没有依赖M的log4j 内部的类。那么log4j 是如何被装蝲的?
Log 是一个接口声明。LogFactory 的内部会去装载具体的日志pȝQƈ获得实现该Log 接口的实现类。而内部有一个Log4JLogger 实现cdLog 接口同时内部提供了对log4j logger 的代理。LogFactory 内部装蝲日志pȝ程Q?
1. 首先Q寻找org.apache.commons.logging.LogFactory 属性配|?
2. 否则Q利用JDK1.3 开始提供的service 发现机制Q会扫描classpah 下的META-INF/services/org.apache.commons.logging.LogFactory 文gQ若扑ֈ则装载里面的配置Q用里面的配置?
3. 否则Q从Classpath 里寻找commons-logging.properties Q找到则Ҏ里面的配|加载?
4. 否则Q用默认的配置Q如果能扑ֈLog4j 则默认用log4j 实现Q如果没有则使用JDK14Logger 实现Q再没有则用commons-logging 内部提供的SimpleLog 实现?
从上q加载流E来看,如果没有做Q何配|,只要引入了log4j q在classpath 配置了log4j.xml Q则commons-logging ׃使log4j 使用正常Q而代码里不需要依赖Q何log4j 的代码?
2.Commons-logging+log4j+slf4j
如果在原有commons-logging pȝ里,如果要迁Udslf4j, 使用slf4j 替换commons-logging Q也是可以做到的。原理用到了上qcommons-logging 加蝲的第二点。需要引入Org.slf4j.jcl-over-slf4j-1.5.6.jar 。这个jar 包提供了一个桥接,让底层实现是Zslf4j 。原理是在该jar 包里存放了配|META-INF/services/org.apache.commons.logging.LogFactory =org.apache.commons.logging.impl.SLF4JLogFactory Q而commons-logging 在初始化的时候会扑ֈq个serviceId Qƈ把它作ؓLogFactory ?
完成桥接后,那么那么单日志门面SLF4J 内部又是如何来装载合适的log 呢?
原理是SLF4J 会在~译时会l定import org.slf4j.impl.StaticLoggerBinder; 该类里面实现对具体日志方案的l定接入。Q何一U基于slf4j 的实现都要有一个这个类。如Q?
org.slf4j.slf4j-log4j12-1.5.6: 提供?log4j 的一U适配实现?
Org.slf4j.slf4j-simple-1.5.6: 是一U?simple 实现Q会?log 直接打到控制台?
……
那么q个地方p注意了:如果有Q意两个实现slf4j 的包同时出现Q那有可能酿就悲剧Q你可能会发现日志不见了、或都打到控制台了。原因是q两个jar 包里都有各自的org.slf4j.impl.StaticLoggerBinder Q编译时候绑定的是哪个是不确定的。这个地方要特别注意Q!出现q几ơ因个导致日志错q问题?
3.Slf4j+logback
Slf4j 和log4j 作者都是同一个h?
Logback L在性能各方面有很多优势Q也很诱人?
直接使用SLf4j 也很单:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
代码里也看不CQ何具体日志实现方案的痕迹?
Logback 没用q,看到q一些诱Zl。具体大家可以去研究。logback ?
注意事项
使用日志配置的时候一定要明白需求,同时避免冲突?
如用SLF4j 的时候ؓ了避免冲H,一定要保障只有一U实现类jar 包在里面?
当遇到日志错q问题Ӟ可以从这几个斚w来排?/span>
webapp
├─META-INF
└─WEB-INF
├─ftl/ (freemaker模板文g)
├─lib/sitemesh-2.4.1.jar
├─decorators.xml
└─web.xml
3、decorators.xml内容如下Q?/span>
<decorators>
</decorators>
(Optional) Create the file [web-app]/WEB-INF/sitemesh.xml that contains the following:
<sitemesh>
<property name="decorators-file" value="/WEB-INF/decorators.xml" />
<excludes file="${decorators-file}" />
<page-parsers>
<parser content-type="text/html"
class="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />
<parser content-type="text/html;charset=ISO-8859-1"
class="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />
</page-parsers>
<decorator-mappers>
<mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
<param name="config" value="${decorators-file}" />
</mapper>
</decorator-mappers>
</sitemesh>
4、修改web.xml 文g如下Q?/span>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
That's it! Your web-app is now setup to use SiteMesh, you can now start building decorators.