(假定通过"logback.xml"文件进行Logback配置)
<!--配置debug=true,从而打印任何内部状态下的信息--> <configuration debug="true"> <!--配置ConsoleAppender实例--> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%-5level %logger %C %M %d{MM/dd-HH:mm:ss.SSS} [%thread] - %msg%n</pattern> </encoder> </appender> <!--可以通过<logger>标签,改变指定的Logger实例的Level值和绑定的Appender--> <!--在Logger实例层次结构中,该Logger实例处于最顶层,其下的子孙Logger实例会继承它的Level值和绑定的Appender,除非特别指定--> <root level="all"> <appender-ref ref="console"/> </root> </configuration>
接下来分别介绍4种场景下的Logback配置方案。
一、直接使用"mysql:mysql-connector-java"<dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version> </dependency> <!--针对数据库管理模块使用Java Logging API日志框架的情况,配置"org.slf4j:jul-to-slf4j"桥接器--> <!--并且修改JDK_HOME/jre/lib/logging.properties文件中的handlers参数值为org.slf4j.bridge.SLF4JBridgeHandler--> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.13</version> </dependency> </dependencies>
2、logback.xml
见“三点注意”中的logback.xml配置。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; public class Simple { public static void main(String[] args) throws Exception { Class.forName("com.mysql.jdbc.Driver"); String mysqlUrl = "jdbc:mysql://127.0.0.1:3306/dslztx?useUnicode=true&characterEncoding=gbk&user=dsl&password=dsl"; String sql = "update activity set origin='china' where id=?"; Connection connection = DriverManager.getConnection(mysqlUrl); PreparedStatement statement = connection.prepareStatement(sql); statement.setInt(1, 1); statement.executeUpdate(); } }
4、运行结果
如图1,通过实验可以得出结论:在本场景中,无论如何配置"logback.xml",都不能达到记录“完整的执行的SQL语句”的目标。图1
<dependencies> <dependency> <groupId>com.googlecode.log4jdbc</groupId> <artifactId>log4jdbc</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version> </dependency> <!--针对数据库管理模块使用Java Logging API日志框架的情况,配置"org.slf4j:jul-to-slf4j"桥接器--> <!--并且修改JDK_HOME/jre/lib/logging.properties文件中的handlers参数值为org.slf4j.bridge.SLF4JBridgeHandler--> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.13</version> </dependency> </dependencies>
2、logback.xml
见“三点注意”中的logback.xml配置。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; public class Log4JDBC { public static void main(String[] args) throws Exception { Class.forName("net.sf.log4jdbc.DriverSpy"); String mysqlUrl = "jdbc:log4jdbc:mysql://127.0.0.1:3306/dslztx?useUnicode=true&characterEncoding=gbk&user=dsl&password=dsl"; String sql = "update activity set origin='china' where id=?"; Connection connection = DriverManager.getConnection(mysqlUrl); PreparedStatement statement = connection.prepareStatement(sql); statement.setInt(1, 1); statement.executeUpdate(); } }
如图2,通过实验可以得出结论:在本场景下,能够达到记录“完整的执行的SQL语句”的目标。
图2
详细分析运行结果,可以发现名称为"jdbc.sqlonly"和"jdbc.sqltiming"的Logger实例能够记录“完整的执行的SQL语句”。因此,我们应该在"logback.xml"中配置这两个Logger实例相应的<logger>标签,将level值设为合适的值,而将<root>标签的level值从"all"改为合适的"非all"值,因为如果Logger实例的Level过低,在项目运行中会有太多有效的日志记录请求,影响项目运行性能。<!--配置debug=true,从而打印任何内部状态下的信息--> <configuration debug="true"> <!--配置ConsoleAppender实例--> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%-5level %logger %C %M %d{MM/dd-HH:mm:ss.SSS} [%thread] - %msg%n</pattern> </encoder> </appender> <!--可以通过<logger>标签,改变指定的Logger实例的Level值和绑定的Appender--> <logger name="jdbc.sqlonly" level="debug" additivitt="true"/> <logger name="jdbc.sqltiming" level="debug" additivitt="true"/> <!--在Logger实例层次结构中,该Logger实例处于最顶层,其下的子孙Logger实例会继承它的Level值和绑定的Appender,除非特别指定--> <root level="info"> <appender-ref ref="console"/> </root> </configuration>
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>3.2.3.RELEASE</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version> </dependency> <!--针对数据库管理模块使用Java Logging API日志框架的情况,配置"org.slf4j:jul-to-slf4j"桥接器--> <!--并且修改JDK_HOME/jre/lib/logging.properties文件中的handlers参数值为org.slf4j.bridge.SLF4JBridgeHandler--> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.13</version> </dependency> </dependencies>
2、logback.xml
见“三点注意”中的logback.xml配置。
3、Java代码
import com.mchange.v2.c3p0.ComboPooledDataSource; import org.springframework.jdbc.core.JdbcTemplate; public class SpringJdbcTemplate { public static void main(String[] args) throws Exception { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/dslztx?useUnicode=true&characterEncoding=gbk"); dataSource.setUser("dsl"); dataSource.setPassword("dsl"); JdbcTemplate template = new JdbcTemplate(dataSource); String sql = "update activity set origin='china' where id=?"; template.update(sql, 1); } }
4、运行结果
如图3,通过实验得出结论:能够达到记录“完整的执行的SQL语句”的目标。
图3
<!--配置debug=true,从而打印任何内部状态下的信息--> <configuration debug="true"> <!--配置ConsoleAppender实例--> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%-5level %logger %C %M %d{MM/dd-HH:mm:ss.SSS} [%thread] - %msg%n</pattern> </encoder> </appender> <!--可以通过<logger>标签,改变指定的Logger实例的Level值和绑定的Appender--> <logger name="org.springframework.jdbc.core.StatementCreatorUtils" level="trace" additivity="true"/> <!--在Logger实例层次结构中,该Logger实例处于最顶层,其下的子孙Logger实例会继承它的Level值和绑定的Appender,除非特别指定--> <root level="info"> <appender-ref ref="console"/> </root> </configuration>
四、使用Mybatis
在本场景中,查询SQL语句的时候,使用“org.mybatis:mybatis","org.mybatis:mybatis"是一个中间层,底层还是使用"mysql:mysql-connector-java"。根据文章 《Java日志框架——Mybatis选用的日志框架解决方案》,"org.mybatis:mybatis"动态确定选用的第三方日志框架,再结合"org.mybatis:mybatis"的pom.xml文件中的对日志框架依赖的"optional"属性值,可以知道,我们只要在项目中加入对SLF4J的依赖,就可以令mybatis使用SLF4J日志框架。<dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version> </dependency> <!--针对数据库管理模块使用Java Logging API日志框架的情况,配置"org.slf4j:jul-to-slf4j"桥接器--> <!--并且修改JDK_HOME/jre/lib/logging.properties文件中的handlers参数值为org.slf4j.bridge.SLF4JBridgeHandler--> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.0.13</version> </dependency> </dependencies>
2、logback.xml
见“三点注意”中的logback.xml配置。
3、Java代码
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; public class MybatisLog { public static void main(String[] args) throws Exception { BufferedReader reader = new BufferedReader(new InputStreamReader(MybatisLog.class.getResourceAsStream("/mybatis-config.xml"))); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, "mybatisDB"); reader.close(); SqlSession sqlSession = factory.openSession(); Map<String, Integer> map = new HashMap<String, Integer>(); map.put("id", 1); sqlSession.update("Activity.updateActivity", map); } }
4、运行结果
如图4,通过实验得到结论:能够达到记录“完整的执行的SQL语句”的目标。
图4
<!--配置debug=true,从而打印任何内部状态下的信息--> <configuration debug="true"> <!--配置ConsoleAppender实例--> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%-5level %logger %C %M %d{MM/dd-HH:mm:ss.SSS} [%thread] - %msg%n</pattern> </encoder> </appender> <!--可以通过<logger>标签,改变指定的Logger实例的Level值和绑定的Appender--> <logger name="Activity.updateActivity" level="debug" additivity="true"/> <!--在Logger实例层次结构中,该Logger实例处于最顶层,其下的子孙Logger实例会继承它的Level值和绑定的Appender,除非特别指定--> <root level="info"> <appender-ref ref="console"/> </root> </configuration>
参考文献:
[1]http://code.google.com/p/log4jdbc/