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