系统在现网环境下运行,有时候会出现响应比较慢的情况,有时候是因为数据库引起的,有时候是由于中间件引起的,也有可能是别的原因引起的,对一个现网系统来说,响应速度是非常重要的,要能够及时方向慢的地方;
还是在现网环境中,特别是一些复杂的数据操作内容,可能不符合数据库的某一些条件导致错误,而我们一般使用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)