1. 概述

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

使用 MyBatis 开发应用时,调试过程中查看执行的 SQL 查询语句往往很有帮助。

本文将探讨如何在 MyBatis 中将 SQL 查询日志输出到控制台。

2. 支持的日志实现

在深入 MyBatis 的 SQL 日志配置前,先了解其支持的日志实现很重要。

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 语句、查询参数和查询结果:

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

输出显示准备了一个从 Address 表获取数据的 SQL 查询,包含参数、结果集列(ADDRESSIDSTREETADDRESS)以及示例数据行(ADDRESSID: 1, STREETADDRESS: 123 Main Street),并显示返回的总行数为 1。

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

⚠️ 使用 stdout 日志的缺点:缺乏细粒度控制。MyBatis 会详细记录所有执行的 SQL 查询,信息量过大可能导致难以聚焦关键信息。

要实现更精确的日志控制(如指定哪个 mapper 打印日志),建议使用日志框架。

4. 配置 MyBatis 的 SLF4J 和 Logback 日志

4.1. 设置 SLF4J 和 Logback 日志

首先,在项目构建文件中添加 SLF4J 和 Logback 依赖。由于 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>

此配置创建根日志记录器,记录 INFO 级别及以上的日志,并通过 stdout appender 输出到控制台。

然后,类似 stdout 日志配置,在 mybatis-config 文件中设置 logImpl 属性为 SLF4J:

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

4.2. 记录 Mapper 日志

按上述配置日志后,记录 mapper 日志变得简单。将日志记录器名称设置为 mapper 接口的全限定名,或 XML mapper 文件的命名空间:

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

通过将日志记录器与目标 mapper 关联,可轻松控制日志。只有与此 mapper 相关的查询才会应用 TRACE 级别日志。

4.3. 记录特定 Mapper 方法

要选择性记录特定方法(如 FruitMapper 中的 getFruitById)的执行日志,可这样配置日志记录器:

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

此配置下,日志记录器仅在执行 getFruitById 方法时打印日志,实现更聚焦的细粒度日志控制。

4.4. 记录包中所有 Mapper

通过将日志记录器名称设置为包名,可轻松启用特定包下所有 mapper 的日志:

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

这种方法可对指定包内的所有 mapper 实现全面日志记录。

4.5. 仅记录 SQL 语句

当查询可能产生大型结果集时,我们可能希望只查看 SQL 语句而不记录实际结果。MyBatis 在 DEBUG 级别记录 SQL 语句,在 TRACE 级别记录结果。若要查看语句但不包含结果,需将日志级别设置为 DEBUG:

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

5. 在 Spring Boot 中配置 MyBatis SQL 日志

Spring 是广泛使用的框架,许多情况下 MyBatis 与 Spring 集成而非独立使用。使用 Spring Boot 时,配置 MyBatis SQL 日志非常简单。Spring Boot 默认使用 logback 作为日志实现,而 MyBatis 的日志机制优先选择 SLF4J。

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

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

通过将指定 mapper 的日志级别设置为 DEBUG,即可获得该 mapper 的详细 SQL 日志。

6. 总结

本文探讨了 MyBatis 中 SQL 日志的配置方案,包括:

  • stdout 日志
  • SLF4J 与 Logback 集成
  • 记录特定 mapper/方法/包的日志
  • 与 Spring Boot 的集成

根据开发阶段和需求选择合适的日志方案,能显著提升调试效率。生产环境推荐使用 SLF4J+Logback 组合,本地开发则可简单粗暴地用 stdout 日志快速定位问题。


原始标题:Logging SQL Queries to the Console in Mybatis | Baeldung