现大家使用的ibatis,hibernate,spring jdbc的sql日志信息,有一点个缺点是占位符与参数是分开打印的,如果想要拷贝sql至PLSQL
Developer客户端直接执行,需要自己拼凑sql。而log4jdbc是在jdbc层的一个日志框架,可以将占位符与参数全部合并在一起显示,方便直接拷贝sql在PLSQL Developer等客户端直接执行,加快调试速度
一.简单介绍:
1.没有使用log4jdbc前sql显示:
select username,password from bitth_date > ? and age < ? and username = ?
2.使用log4jdbc后sql显示:
select username,password from bitth_date > to_date(‘2010-11-11’,’yyyy-mm-dd’) and age < 20 and username = ‘qq2008’ {executed in 2 msec}
这样就可以直接拷贝上面的sql在PLSQL直接执行. 最后的 {executed in 2 msec} 为SQL执行时间.而如果mysql,日志信息将不会出现 to_date()
二.log4jdbc使用:
1.spring
xml配置(拦截需要处理的dataSource连接)
<bean id="log4jdbcInterceptor" class="net.sf.log4jdbc.DataSourceSpyInterceptor" />
<bean id="dataSourceLog4jdbcAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>log4jdbcInterceptor</value>
</list>
</property>
<property name="beanNames">
<list>
<value>dataSource</value>
</list>
</property>
</bean>
DataSourceSpyInterceptor是一个拦截器类,扩展主要是使用AOP的方式。具体源码为:
/**实现方法拦截器*/
public class DataSourceSpyInterceptor implements MethodInterceptor
{
private RdbmsSpecifics rdbmsSpecifics = null;
private RdbmsSpecifics getRdbmsSpecifics(Connection conn)
{
if (this.rdbmsSpecifics == null)
this.rdbmsSpecifics = DriverSpy.getRdbmsSpecifics(conn);
return this.rdbmsSpecifics;
}
public Object invoke(MethodInvocation invocation) throws Throwable
{
Object result = invocation.proceed();
if (SpyLogFactory.getSpyLogDelegator().isJdbcLoggingEnabled() && (result instanceof Connection))
{
Connection conn = (Connection)result;
return new ConnectionSpy(conn, getRdbmsSpecifics(conn));
}
return result;
}
}
MySql日期处理:
class MySqlRdbmsSpecifics extends RdbmsSpecifics
{
MySqlRdbmsSpecifics()
{
super();
}
String formatParameterObject(Object object)
{
if (object instanceof java.sql.Time)
{
return "'" + new SimpleDateFormat("HH:mm:ss").format(object) + "'";
}
else if (object instanceof java.sql.Date)
{
return "'" + new SimpleDateFormat("yyyy-MM-dd").format(object) + "'";
}
else if (object instanceof java.util.Date) // (includes java.sql.Timestamp)
{
return "'" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(object) + "'";
}
else
{
return super.formatParameterObject(object);
}
}
}
Oracle日期处理class OracleRdbmsSpecifics extends RdbmsSpecifics
{
OracleRdbmsSpecifics()
{
super();
}
String formatParameterObject(Object object)
{
if (object instanceof Timestamp)
{
return "to_timestamp('" + new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS").format(object) + "', 'mm/dd/yyyy hh24:mi:ss.ff3')";
}
else if (object instanceof Date)
{
return "to_date('" + new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(object) + "', 'mm/dd/yyyy hh24:mi:ss')";
}
else
{
return super.formatParameterObject(object);
}
}
}
2.log4j.properties配置:
log4j.rootLogger=INFO,stdout,R_ERROR
log4j.logger.asyncAppenders=INFO,stdout,logfileWarn
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%p] [%d{yyyy-MM-dd HH:mm:ss}] [%c:%L] - %m%n
#log4jdbc config
log4j.logger.jdbc.sqlonly=OFF
log4j.logger.jdbc.sqltiming=INFO
log4j.logger.jdbc.audit=OFF
log4j.logger.jdbc.resultset=OFF
log4j.logger.jdbc.connection=OFF
#log4jdbc config end
log4j.logger.org.springframework.beans.factory.support.DefaultListableBeanFactory=ERROR,logfileWarn
log4j.logger.org.springframework.web.servlet.DispatcherServlet=ERROR,logfileWarn
log4j.logger.org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping=ERROR,logfileWarn
log4j.logger.com.shareinfo=DEBUG,logfileWarn
#hibernate
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.type=ERROR
#mybatis
log4j.logger.com.ibatis=DEBUG
log4j.logger.org.apache.ibatis.jdbc.ScriptRunner=DEBUG
log4j.logger.org.mybatis.spring=INFO
log4j.logger.org.apache.ibatis=DEBUG,stdout
log4j.appender.logfileWarn=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfileWarn.File=${catalina.base}/logs/warn.log
log4j.appender.logfileWarn.DatePattern='.'yyyy-MM-dd-HH
log4j.appender.logfileWarn.layout=com.netflix.logging.log4jAdapter.NFPatternLayout
log4j.appender.logfileWarn.Append=true
log4j.appender.logfileWarn.layout.ConversionPattern=[%p -> %c:%L] %d{yyyy-MM-dd HH:mm:ss} %m%n
log4j.appender.logfileWarn.Threshold=DEBUG
log4j.appender.R_ERROR=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R_ERROR.Threshold=ERROR
log4j.appender.R_ERROR.File=${catalina.base}/logs/error.log
log4j.appender.R_ERROR.Append=true
log4j.appender.R_ERROR.DatePattern='.'yyyy-MM-dd
log4j.appender.R_ERROR.layout=com.netflix.logging.log4jAdapter.NFPatternLayout
log4j.appender.R_ERROR.layout.ConversionPattern=[%p -> %c:%L] %d{yyyy-MM-dd HH:mm:ss} %m%n
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
(日志信息如果全部为off,log4jdbc将不会生效,因此对性能没有任何影响)
log4jdbc需要依赖slf4j日志框架说明:本人于ITEYE创建于2014年,现转移到优快云