记性不如烂笔头14-使用log4jdbc显示完整SQL语句和执行时间


系统在现网环境下运行,有时候会出现响应比较慢的情况,有时候是因为数据库引起的,有时候是由于中间件引起的,也有可能是别的原因引起的,对一个现网系统来说,响应速度是非常重要的,要能够及时方向慢的地方;

还是在现网环境中,特别是一些复杂的数据操作内容,可能不符合数据库的某一些条件导致错误,而我们一般使用ibatis,hibernate,spring这些工具打印的jdbc的sql日志信息,有一点个缺点是占位符与参数是分开打印的,如果想要拷贝sql至PLSQL Developer客户端直接执行,需要自己拼凑sql。

log4jdbc是在jdbc层的一个日志框架,可以将占位符与参数全部合并在一起显示,并且可以显示SQL语句执行的时间,可以方便的解决上面两个问题。

1、在java的应用系统中log4jdbc的基本使用

相关必备包:分别是log4jdbc包,SLF4j包,log4j包;

1.1.选择相关JAR包和版本

log4jdbc3-1.2beta2.jar    for JDBC 3support in JDK 1.4 , JDK 1.5

log4jdbc4-1.2beta2.jar    for JDBC 4support in JDK 1.6 , JDK 1.7

需要使用SLF4j,主要是slf4j-api-1.7.10.jar和slf4j-log4j12-1.7.10.jar

需要log4j对应的包,log4j-1.2.16.jar

1.2.设置jdbc driver

如:在jdbc.properties中将原先的jdbc.driver=oracle.jdbc.driver.OracleDriver

修改为jdbc.driver=net.sf.log4jdbc.DriverSpy

1.3.修改jdbc url

在jdbc.properties中将原先的jdbc.url=jdbc:oracle:thin:@192.168.1.1:1521:ffm

修改为 jdbc.url=jdbc:log4jdbc:oracle:thin:@192.168.1.1:1521:ffm

1.4. 设置logger

如在控制台仅需要输出sql语句的log4j.properties

log4j.logger.jdbc.sqlonly=DEBUG,sql log4j.additivity.jdbc.sqlonly=truelog4j.appender.sql=org.apache.log4j.ConsoleAppenderlog4j.appender.sqlThreshold=debug log4j.appender.sqlTarget=System.out log4j.appender.sqlEncoding=GBKlog4j.appender.sql.layout=org.apache.log4j.PatternLayoutlog4j.appender.sql.layout.ConversionPattern=-----> %d{yyyy-MM-ddHH:mm:ss.SSS} %m%n%n

1.5.其他注意事项

在学习log4jdbc之前,最好有一个能访问数据库的应用,这样改造起来最简单

2、log4jdbc应用的源代码

本质上来说,改变的知识配置文件,而不是源代码

package com.db;

 

import java.io.IOException;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.SQLException;

import java.util.Properties;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

 

importorg.apache.commons.dbcp.BasicDataSource;

importorg.apache.commons.dbcp.BasicDataSourceFactory;

import org.apache.commons.dbutils.QueryRunner;

 

/**

 *本应用作为servlet简单模拟使用log4jdbc访问数据库,对一个普通的应用来说,只需要在配置上做调整;

 *如果用spring等框架,要加在spring的拦截器上;

 *@author 范芳铭

 */

public class Log4JDBCTest  extends HttpServlet{

    staticConfigurationUsage propManager = null;

    privatestatic BasicDataSource dataSourceBM = null;

 

    //bm

    publicstatic void initBM() {

        if(dataSourceBM != null) {

            try{

                dataSourceBM.close();

            }catch (Exception e) {

                e.printStackTrace();

            }

            dataSourceBM= null;

        }

        try{  

            Propertiesp = new Properties();

            p.setProperty("driverClassName",propManager.getInstance().getProperty("jdbc.bm.driverClassName"));

            p.setProperty("url",propManager.getInstance().getProperty("jdbc.bm.url"));

            p.setProperty("password",propManager.getInstance().getProperty("jdbc.bm.username"));

            p.setProperty("username",propManager.getInstance().getProperty("jdbc.bm.password"));

            p.setProperty("maxActive",propManager.getInstance().getProperty("jdbc.bm.maxActive"));

            p.setProperty("maxIdle",propManager.getInstance().getProperty("jdbc.bm.maxIdle"));

            p.setProperty("maxWait",propManager.getInstance().getProperty("jdbc.bm.maxWait"));

 

            dataSourceBM= (BasicDataSource) BasicDataSourceFactory

                    .createDataSource(p);

        }catch (Exception e) {

            e.printStackTrace();

        }

    }

 

   

    publicstatic synchronized Connection getConnBM() throws SQLException {

        if(dataSourceBM == null) {

            initBM();

        }

        Connectionconn = null;

        if(dataSourceBM != null) {

            conn= dataSourceBM.getConnection();

        }

        returnconn;

    }

   

    privateQueryRunner runner = null;

 

 

    //使用上,和没有用Log4jdbc一样,没有区别

    publicvoid doGet(HttpServletRequest request, HttpServletResponse response)

            throws ServletException,IOException {

       String sql = " select sysdate from dual where rownum < ? ";

       Connection con = null;

       PreparedStatement pstmt = null;

       try {

           con = Log4JDBCTest.getConnBM();

            pstmt = con.prepareStatement(sql);

            pstmt.setString(1, "2");//显示第一条

            boolean executeResult =pstmt.execute();

            System.out.println("数据库访问完成");

       } catch (SQLException e) {

            e.printStackTrace();

       }finally{

            try {

                pstmt.close();

                con.close();

            } catch (SQLException e) {

                e.printStackTrace();

            }

       }

   }

 

   public void doPost(HttpServletRequest request, HttpServletResponseresponse)

            throws ServletException,IOException {

       this.doGet(request, response);

   }

}

一个读配置文件的辅助类:

package com.db;

 

importorg.apache.commons.configuration.CompositeConfiguration;

importorg.apache.commons.configuration.ConfigurationException;

import org.apache.commons.configuration.PropertiesConfiguration;

 

/**

 *@author 范芳铭

 */

public class ConfigurationUsage {

    privateConfigurationUsage() {

    }

 

    privatestatic ConfigurationUsage propManager;

 

    publicsynchronized static ConfigurationUsage getInstance() {

        if(propManager == null) {

            propManager= new ConfigurationUsage();

        }

        returnpropManager;

    }

 

    publicstatic CompositeConfiguration config = new CompositeConfiguration();

    static{

        try{

            config.addConfiguration(newPropertiesConfiguration(

                    "dbconfig.properties"));

        }catch (ConfigurationException e) {

            e.printStackTrace();

        }

    }

 

    publicString getProperty(String key) {

        returnconfig.getString(key);

    }

}

配置文件(修改后):

jdbc.bm.driverClassName=net.sf.log4jdbc.DriverSpy

jdbc.bm.url=jdbc:log4jdbc:oracle:thin:@192.168.1.1:1521:ffm

jdbc.bm.username=ffm

jdbc.bm.password=ffm

jdbc.bm.maxActive=5

jdbc.bm.maxIdle=2

jdbc.bm.maxWait=200

修改前为:

jdbc.bm.driverClassName= oracle.jdbc.driver.OracleDriver

jdbc.bm.url=jdbc:oracle:thin:@192.168.1.1:1521:ffm

jdbc.bm.username=ffm

jdbc.bm.password=ffm

jdbc.bm.maxActive=5

jdbc.bm.maxIdle=2

jdbc.bm.maxWait=200

 

3、运行结果

4、2015-02-0214:18:57.376 org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)

5、2. select sysdate fromdual where rownum < ‘2‘

6、 

7、2015-02-02 14:18:57.521select sysdate from dual where rownum < ‘2‘ {executed in 145 msec}

8、 

9、数据库访问完成

 

我们能看到运行的SQL语句,也可以看到花费的时间(executed in 67msec)

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。