1.3mybatis打印sql⽇志
1.3 mybatis打印sql⽇志
mybatis⽀持使⽤多种⽇志框架来打印sql,包括:slf4j、commons-logging、log4j、log4j2、jdk logging、stdout、no logging等。因此在打印⽇志时,我们⾸要确定⾃⼰使⽤的⽇志框架是什么,然后进⾏相应的配置。
对于从本教程刚刚开始学习mybatis的读者,可以在项⽬中引⼊log4j的依赖,然后在classpath下新增配置⽂件log4j.properties,即可打印出sql,内容如下:
# 设置root logger⽇志打印级别为INFO,⽇志输出到STDOUT这个appender中
# 定义stdout这个STDOUT,其实现类为ConsoleAppender.表⽰⽇志输出到控制台中,读者可以使⽤其他appender,如DailyRollingFileAppender
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%d[%t]%-5p %c%x-%m%n
下⾯的内容,主要针对已经有⼀定mybatis使⽤经验,但是被打印sql的问题所困扰的⽤户。笔者在2.1、2.2、2.3⼩节中分别列出了
log4j、log4j2、loback的配置⽅式 。但是还是希望读者按照顺序阅读,笔者将会通过深⼊的讲解,让你彻底掌握这个问题。
在使⽤mybatis打印sql⽇志时需要注意的⼏点,笔者⾄于让读者彻底掌握不同版本的mybatis如何打印⽇志。
1. 打印sql⽇志的logger⼀定要是debug级别的(注意这⾥说的不是root logger’),在其他级别下不论如何配置,mybatis也不会打印
sql⽇志。
2. mybatis
3.0.6,3.1.0,3.2.0版本前后打印⽇志的配置⽅式是不同的,这也是我们经常在⽹上照搬⼀些配置,但是依然打印不了sql
的原因。
3. 当应⽤中存在多种⽇志框架jar包的依赖时,如果没有进⾏合适的配置,也是⽆法打印sql的。例如slf4j和commons-logging都是
facade设计模式的实现,⽤于统⼀各种⽇志框架,底层依赖于具体的⽇志框架实现如log4j、logback、log4j2、jdk logging,并且需要引⼊相应的桥接jar依赖。
4. mybatis 版本>=3.2.0之后,<settings>元素中提供了logPrefix和logImpl配置项来帮助配置⽇志框架,这也是笔者建议的mybatis⽇
志打印⽅式
1 不同版本的mybatis的⽇志实现
mybatis打印⽇志是通过org.apache.ibatis.logging.jdbc包下⾯
的ConnectionLogger、StatementLogger、PreparedStatementLogger和ResultSetLogger进⾏的。在mybatis 3.0.6,3.1.0,3.2.0之后,这⼏个类的实现⽅式各不相同,导致打印sql⽇志的配置⽅式也发⽣了变化。
下⾯分别介绍不同的mybatis版本中,实现的区别。
1.1 不同版本logger实现的区别
以PreparedStatementLogger为例,不同版本的实现如下所⽰:
mybatis版本<=3.0.6
3.0.6<mybatis版本<3.2.0
这两个版本之间只发布了3.1.0和3.1.1两个版本,以3.1.1版本为例,PreparedStatementLogger实现如下:
mybatis>=3.2.0
1.2 不同版本的⽇志打印效果演⽰
不同版本实现的区别在于logger的名称不同,以log4j为例:
1.2.1 mybatis版本<=3.0.6
logger的名字都以java.sql为前缀。我们可以按照如下⽅式配置log4j.properties
# 设置root logger⽇志打印级别为INFO,⽇志输出到STDOUT这个appender中
# 定义stdout这个STDOUT,其实现类为ConsoleAppender.表⽰⽇志输出到控制台中,读者可以使⽤其他appender,如DailyRollingFileAppender log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%d[%t]%-5p %c%x-%m%n
#设置mybatis打印sql⽇志
log4j.logger.java.sql=DEBUG
#等价于以下四⾏配置
#log4j.logger.java.sql.Connection=DEBUG
#log4j.logger.java.sql.Statement=DEBUG
#log4j.logger.java.sql.PreparedStatement=DEBUG
#log4j.logger.java.sql.ResultSet=DEBUG
此时打印的⽇志效果如下所⽰:
2017-11-2722:18:58,128[main]DEBUG java.sql.Connection - ooo Connection Opened
2017-11-2722:18:58,240[main]DEBUG java.sql.PreparedStatement -==> Executing: select id,name,age from user where id=?
2017-11-2722:18:58,241[main]DEBUG java.sql.PreparedStatement -==> Parameters:1(Integer)
2017-11-2722:18:58,270[main]DEBUG java.sql.ResultSet -<==  Columns: id, name, age
2017-11-2722:18:58,270[main]DEBUG java.sql.ResultSet -<==  Row:1, tianshouzhi,26
2017-11-2722:18:58,272[main]DEBUG java.sql.Connection - xxx Connection Closed
1.2.2 mybatis>=3.2.0
默认logger的名字为namespace.id。其中namespace指的是mapper映射⽂件的namespace属性,id指的是配置的sql的id属性。
此时我们可以按照如下⽅式配置log4j.properties
# 设置root logger⽇志打印级别为INFO,⽇志输出到STDOUT这个appender中
# 定义stdout这个STDOUT,其实现类为ConsoleAppender.表⽰⽇志输出到控制台中,读者可以使⽤其他appender,如DailyRollingFileAppender
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%d[%t]%-5p %c%x-%m%n
#设置mybatis打印sql⽇志,其中batis是所有mapper映射⽂件namespace属性的公共前缀
log4j.batis=DEBUG
这⾥配置了⼀个logger,名字为batis,其是所有mapper映射⽂件namespace属性的公共前缀。
此时打印效果如下:
2017-11-2722:58:30,816[main]DEBUG batis.quickstart.stResultMap - ooo Using Connection [sql.jdbc. JDBC4Connection@5c533a2]
2017-11-2722:58:30,819[main]DEBUG batis.quickstart.stResultMap -==> Preparing: select id,name,age from  user where id=?
2017-11-2722:58:30,911[main]DEBUG batis.quickstart.stResultMap -==> Parameters:1(Integer)
这种⽅式的好处是,⼀个sql执⾏过程中,经历的ConnectionLogger、StatementLogger、PreparedStatementLogger和ResultSetLogger内部在打印⽇志时,内部实际上引⽤的都是同⼀个底层lo
gger实例。⽽通过namespace.sqlId作为logger的名称,在查看⽇志时,很容易串联起来⼀个sql从获取连接–>执⾏–>结果封装的整个过程。
特别的,mybatis 3.2.0版本中,我们可以在l⽂件中的在settings元素中可以配置logPrefix和logImpl配置项。例如,如果我们的项⽬中,mapper映射⽂件的namespace属性值各不相同,此时我们可以为所有的logger的名字加上⼀个公共的前缀,如:
<settings>
<!--logger公共前缀,value值随意,不过记得加上⼀个"."-->
<setting name="logPrefix"value="mybatis."/>
</settings>
此时修改log4.properties配置如下:
# 设置root logger⽇志打印级别为INFO,⽇志输出到STDOUT这个appender中
# 定义stdout这个STDOUT,其实现类为ConsoleAppender.表⽰⽇志输出到控制台中,读者可以使⽤其他appender,如DailyRollingFileAppender
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%d[%t]%-5p %c%x-%m%n
# 设置mybatis打印sql⽇志,注意这⾥的mybatis与logPrefix相匹配
batis=DEBUG
此时sql的打印效果如下:
2017-11-2722:59:21,622[main]DEBUG batis.quickstart.stResultMap - ooo Using Connection [ sql.jdbc.JDBC4Connection@66869e50]
2017-11-2722:59:21,625[main]DEBUG batis.quickstart.mapper.UserMapp
2017-11-2722:59:21,676[main]DEBUG batis.quickstart.stResultMap -==> Parameters:1(Integer)
可以看到,所有的logger的名字前⾯,都有⼀个mybatis前缀。
1.2.3 3.0.6<mybatis版本<3.2.0
log4j2不打印日志
这两个版本之间,mybatis⽇志实现处于过度阶段,因此同时兼容以上两种配置。需要注意的是,logImpl和logPrefix从3.2.0版本才开始⽀持,因此如果3.0.6<mybatis版本<3.2.0,配置这两个属性会报错。
2 不同⽇志框架的配置
2.1 log4j配置
<!--log4j依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--slf4j依赖-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!--桥接-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
其中slf4j和slf4j-log4j12是⽤于桥接⽤的,可以不引⼊。但是如果想⽤log4j作为⽇志框架,且项⽬中依赖了slf4j,就⼀定要引⼊slf4j-log4j12。
log4j.properties
# 设置root logger⽇志打印级别为INFO,⽇志输出到STDOUT这个appender中
# 定义stdout这个STDOUT,其实现类为ConsoleAppender.表⽰⽇志输出到控制台中,读者可以使⽤其他appender,如DailyRollingFileAppender
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%d[%t]%-5p %c%x-%m%n
# 设置mybatis打印sql⽇志>>#### mybatis<=3.0.6 >>>
# logger名称以java.sql为前缀
log4j.logger.java.sql=DEBUG
>>>#### 3.0.6<mybatis<3.2.0 >>>>###
# 1、兼容3.0.6之间的配置
# 2、且⽀持logger名称由namespace.id组成,这⾥的"batis"是namespace的公共前缀,读者⾃⾏修改
# log4j.batis=DEBUG
>>>#### mybatis>3.2.0 >>>>###
# 1、⽀持logger名称由namespace.id组成
# 2、⽀持在<settings>元素中配置logPrefix,例如这⾥配置了logPrefix的值为"mybatis.",则可以按照如下⽅式配置logger
# batis=DEBUG
2.2 log4j2配置
mybatis在3.2.3之前,并不直接⽀持log4j2作为⽇志框架,必须通过slf4j或者commons-logging来做桥接。
为了避免这些问题,在使⽤log4j2作为⽇志框架的话,建议直接使⽤slf4j做桥接。
<!--slf4j依赖-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!--桥接-->
<dependency>
<!-- 桥接:告诉Slf4j使⽤Log4j2 -->
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.3</version>
</dependency>
<!--log4j2依赖-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.3</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console"target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<!--配置mybatis打印sql⽇志-->
<!-- mybatis < 3.2.0  name可以设置为java.sql-->
<!-- mybatis > 3.1.0  name可以设置为java.sql 或者namespace属性值的前缀-->
<!-- mybatis >= 3.2.0 name可以设置为通过logPrefix设置的前缀-->
<Logger name="com.tianshouzhi"level="debug"additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
2.3 logback配置
mybatis并不⽀持直接使⽤logback作为⽇志框架, 如果要使⽤logback的话,必须使⽤slf4j做桥接。pom中引⼊如下依赖:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论