sql日志框架log4jdbc的AOP式使用

log4jdbc.log4j2

参考:1.  http://badqiu.iteye.com/blog/743100
 2.  https://code.google.com/p/log4jdbc/
 3.  https://code.google.com/p/log4jdbc-log4j2/
  1. 引入项目依赖
    1
    2
    3
    4
    5
    <dependency>
        <groupId>org.bgee.log4jdbc-log4j2</groupId>
        <artifactId>log4jdbc-log4j2-jdbc4</artifactId>
        <version>1.16</version>
    </dependency>
  2. 扩展的一个拦截器类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    public class DataSourceSpyInterceptor implements MethodInterceptor {
         
        private RdbmsSpecifics rdbmsSpecifics = null
         
        private static Method method = null;
         
        private RdbmsSpecifics getRdbmsSpecifics(Connection conn) {
            if(rdbmsSpecifics == null) {
                try {
                    if (null ==  method) {
                        method = DriverSpy.class.getDeclaredMethod("getRdbmsSpecifics", Connection.class);
                    }
                    method.setAccessible(true);
                    rdbmsSpecifics = (RdbmsSpecifics) method.invoke(null, conn);
                    method.setAccessible(false);
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
            return rdbmsSpecifics;
        
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
             Object result = invocation.proceed(); 
                if(SpyLogFactory.getSpyLogDelegator().isJdbcLoggingEnabled()) { 
                    if(result instanceof Connection) {
                        Connection conn = (Connection)result; 
                        return new ConnectionSpy(conn,getRdbmsSpecifics(conn),SpyLogFactory.getSpyLogDelegator()); 
                    }
                }
                return result;
        }
    }
  3. 配置spring配置文件applicationContext.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <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>

    其中net.sf.log4jdbc.DataSourceSpyInterceptor为刚刚新建拦截器所在路径

  4. 配置你的日志配置文件,我的项目用的是logback,在logback.xml中配置

    1
    2
    3
    4
    5
    <!--log4jdbc -->
    <logger name="jdbc.sqltiming" level="DEBUG"/>
    <logger name="jdbc.sqlonly" level="DEBUG"/>
    <logger name="jdbc.audit" level="ERROR"/>
    <logger name="jdbc.connection" level="DEBUG"/>

    配置说明请参考https://code.google.com/p/log4jdbc-log4j2/ 中的说明4.2.2. Configure the loggers

    现在你的日志文件中就会有优雅的 SQL 语句打印出来了,对原项目基本没有影响

 

PS:

遇到这样的exception :

org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.AbstractMethodError: oracle.jdbc.driver.OracleResultSetImpl.isClosed()Z

简单点的解决办法是降低版本:

    <dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc3</artifactId>
<version>1.16</version>
</dependency>
上一篇:【Java并发系列04】线程锁synchronized和Lock和volatile和Condition


下一篇:Python使用正则表达式分割字符串