配置 Mybatis 的 SQL 查询日志

1、概览

MyBatis 是 Java 界流行的持久化框架,它通过将 SQL 查询映射到 Java 方法来简化数据库操作。

在使用 MyBatis 开发应用时,查看正在执行的 SQL 查询通常对调试很有用,本文将带你了解如何在 MyBatis 中将 SQL 查询日志输出到控制台。

2、支持的日志实现

MyBatis 是一个灵活的框架,可以与各种日志框架集成,包括 SLF4JApache Commons LoggingLog4j 2JDK Logging。本文主要关注 Stdout (标准输出,即控制台)日志和 SLF4J

Stdout 日志在本地功能开发过程中非常有用,它提供了一种简单的调试方法。而 SLF4J 更适合生产应用,它提供了更高级的抽象,可与其他的日志框架无缝集成。

3、在 MyBatis 中配置 Stdout 日志

使用 stdout 记录 MyBatis SQL,可以直接在控制台上查看执行的 SQL 语句。这种方法在开发和调试过程中非常方便。

要启用 MyBatis SQL 的 stdout 日志,需要在应用的 mybatis-config 文件中添加日志设置:

<configuration>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>

logImpl 属性配置为 STDOUT_LOGGING 后,MyBatis 将在执行 SQL 查询时输出原始 SQL 语句、查询参数和查询结果。输出通常包括执行的 SQL、绑定的参数和返回的结果集等详细信息:

==>  Preparing: SELECT addressId, streetAddress FROM Address WHERE addressId = ? 
==> Parameters: 1(Integer)
<==    Columns: ADDRESSID, STREETADDRESS
<==        Row: 1, 123 Main Street

除了可以在 mybatis-config 中配置 logImpl 属性,还可以选择以编程方式设置日志实现。在调用任何其他 MyBatis 方法前调用静态方法 LogFactory.useStdOutLogging() 来设置。

使用 stdout 日志有一个缺点,那就是缺乏对日志的精细控制。使用 stdout 日志时,MyBatis 会详细记录所有执行的 SQL 查询,这可能会让人难以专注于重要信息。

要更精确地控制日志记录,例如要输出哪个 mapper 的 SQL 日志,建议使用日志框架。

4、MyBatis 配置 SLF4J 和 Logback 日志

4.1、设置 SLF4J 和 Logback 日志

首先,需要在项目的构建文件中添加 SLF4JLogback 依赖。由于 Logback 会自动将 SLF4J 作为传递依赖,因此对于 Maven 项目,只需在 pom.xml 文件中指定 Logback 依赖即可:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.4.14</version>
</dependency>

接下来,需要创建一个 Logback 配置文件(通常名为 logback.xml)来定义日志记录行为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%5level [%thread] - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="stdout"/>
    </root>
</configuration>

此配置创建了一个 root logger,用于记录日志级别为 INFO 或更高的信息,并将其指定至 stdout Appender,以输出到控制台。

之后,与 stdout 日志配置类似,需要在 mybatis-config 文件中将 logImpl 属性设置为 SLF4J

<configuration>
    <settings>
        <setting name="logImpl" value="SLF4J" />
    </settings>
</configuration>

4.2、Mapper 日志

如上所述,通过日志配置,mapper 的日志变得简单明了。我们可以将 logger 名称设置为 mapper 接口的全称,如果使用的是 XML mapper 文件,则设置为命名空间(namespace):

<logger name="com.baeldung.mybatis.mapper.AddressMapper" level="TRACE"/>

这样,通过将 logger 与所需的 mapper 关联起来,就能轻松实现日志控制。只有与该 mapper 相关的查询才会输出相应日志级别的日志记录。

4.3、Mapper 方法日志

要选择性地记录特定方法(如 FruitMapper 中的 getFruitById)的执行日志,可以配置相应的 logger:

<logger name="com.baeldung.mybatis.mapper.AddressMapper.getAddresses" level="TRACE"/>

使用此配置后,logger 只会在执行 getFruitById 方法时将日志输出到控制台,从而实现更集中、更细粒度的日志控制。

4.4、Mapper 包日志

通过将日志 logger 名称设置为 package 名称,可以轻松启用特定 package 下所有 mapper 的日志记录功能:

<logger name="com.baeldung.mybatis.mapper" level="TRACE"/>

这种方法可以记录指定 package 内的所有 mapper 的执行日志。

4.5、仅记录 SQL 语句

在查询会产生大量结果集的情况下,可以只记录 SQL 语句,而不记录实际结果。MyBatis 的设计是在 DEBUG 级别记录 SQL 语句,而在 TRACE 级别记录结果。如果想只查看语句而不查看结果,就需要将日志级别设为 DEBUG

<logger name="com.baeldung.mybatis.mapper.AddressMapper" level="DEBUG"/>

5、在 Spring Boot 中配置 MyBatis 日志

Spring 是一个非常流行的框架,一般情况下,大多数的 Spring 应用都会使用 MyBatis 作为持久层框架(特别是在中国)。在使用 Spring Boot 时,几乎不需要配置 MyBatis SQL 日志。Spring Boot 使用 Logback 作为默认日志实现,而 MyBatis 的日志机制优先使用 SLF4J(Logback 实现了 SLF4J)。

因此,要为特定 mapper 启用 MyBatis SQL 日志,只需要在 Spring Boot application.properties 文件中添加配置属性:

logging.level.com.baeldung.mybatis.spring.ArticleMapper=DEBUG

将指定 mapper 的日志级别配置为 DEBUG 来为该 mapper 启用详细的 SQL 日志输出。

6、总结

本文介绍了 MyBatis 中 SQL 日志的配置,包括 stdout 日志、使用 Logback 和 SLF4J、特定 Mapper/方法/package 的日志,以及与 Spring Boot 的集成。


Ref:https://www.baeldung.com/java-sql-mybatis-log-sql-queries