mybatis 打印sql(保姆级教程)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

在数据库开发中,SQL 语句的执行效率与准确性直接影响应用程序的性能和稳定性。对于使用 MyBatis 框架的开发者而言,mybatis 打印sql 是调试、优化和排查问题的核心手段之一。无论是初学者调试新手代码,还是中级开发者定位复杂场景的性能瓶颈,掌握这一技能都能显著提升开发效率。本文将从 MyBatis 的日志配置、参数占位符解析、实际案例分析等角度,系统讲解如何通过 mybatis 打印sql 提升开发能力。


一、MyBatis 日志配置基础

1.1 MyBatis 日志框架简介

MyBatis 本身不直接处理日志输出,而是依赖第三方日志框架(如 Log4j、Logback、SLF4J)。因此,要实现 mybatis 打印sql,需要先配置这些框架的输出规则。

核心配置步骤:

  1. 引入日志依赖:在项目中添加日志框架的 Maven 依赖,例如:
    <!-- Logback 配置示例 -->  
    <dependency>  
      <groupId>ch.qos.logback</groupId>  
      <artifactId>logback-classic</artifactId>  
      <version>1.2.10</version>  
    </dependency>  
    
  2. 配置日志级别:在 logback.xmllog4j.properties 中设置 MyBatis 的日志输出级别为 DEBUG,例如:
    <!-- Logback 配置片段 -->  
    <logger name="com.example.mapper" level="DEBUG"/>  
    <logger name="com.ibatis" level="DEBUG"/>  
    <logger name="org.apache.ibatis" level="DEBUG"/>  
    

    这里的关键点在于:只有将日志级别设置为 DEBUG 或更低时,MyBatis 才会输出 SQL 语句。

常见误区:

  • 未正确引入日志依赖:可能导致 MyBatis 日志无法输出,需检查依赖是否冲突或版本兼容性。
  • 日志级别设置错误:例如误将级别设为 INFO,此时 SQL 语句不会被打印。

1.2 参数占位符与 SQL 语句的显示形式

MyBatis 默认会将 SQL 中的参数占位符(如 #{id})替换为实际值,但这一行为可通过配置调整。

案例对比:

情况1:未启用参数替换

// Mapper 接口  
int insertUser(@Param("id") Integer userId, @Param("name") String username);  

对应的 SQL 语句可能显示为:

INSERT INTO users (id, name) VALUES (?, ?)  

此时,参数值不会被直接打印,仅显示占位符。

情况2:启用参数替换
若在日志配置中开启参数解析(例如通过 Log4j 的 format 属性),SQL 语句会显示为:

INSERT INTO users (id, name) VALUES (1001, 'Alice')  

这一功能对调试参数传递错误(如参数绑定失败)非常有用。


二、实战:通过不同场景实现 mybatis 打印sql

2.1 基础场景:简单查询语句

步骤1:配置日志输出

application.propertieslog4j.properties 中设置:

log4j.logger.org.apache.ibatis=DEBUG  

步骤2:编写 Mapper 接口与 XML

// UserMapper.java  
public interface UserMapper {  
    User selectUserById(@Param("id") Integer id);  
}  

对应的 XML 文件:

<select id="selectUserById" resultType="User">  
    SELECT * FROM users WHERE id = #{id}  
</select>  

步骤3:运行并观察日志

执行查询操作后,控制台将输出类似以下内容:

DEBUG o.a.i.s.t.SqlSourceBuilder - Created SQL [SELECT * FROM users WHERE id = ?]  
DEBUG o.a.i.s.o.BaseExecutor - ==>  Preparing: SELECT * FROM users WHERE id = ?  
DEBUG o.a.i.s.o.BaseExecutor - ==> Parameters: 1001(Integer)  

通过分析这些日志,可以快速确认 SQL 语句的结构和参数是否正确。


2.2 复杂场景:分页查询与参数占位符

在使用分页插件(如 PageHelper)时,原生 SQL 可能被动态修改,此时 mybatis 打印sql 的输出会反映这一变化。

示例代码:

// Service 层调用  
PageHelper.startPage(1, 10);  
List<User> users = userMapper.selectAllUsers();  

对应的 SQL 日志可能显示为:

DEBUG o.a.i.s.o.BaseExecutor - ==>  Preparing: SELECT * FROM (SELECT users.*, ROWID AS ___rowid___ FROM users) WHERE ___rowid___ BETWEEN 1 AND 10  
DEBUG o.a.i.s.o.BaseExecutor - ==> Parameters:  

通过分析这一输出,开发者可以验证分页插件是否正确修改了 SQL 逻辑。


2.3 性能优化场景:通过 SQL 日志定位慢查询

当发现某接口响应缓慢时,可以通过 mybatis 打印sql 定位执行时间较长的 SQL 语句。

日志片段示例:

DEBUG o.a.i.s.o.BaseExecutor - ==>  Preparing: SELECT * FROM orders WHERE user_id = ? AND status = ?  
DEBUG o.a.i.s.o.BaseExecutor - ==> Parameters: 1001(Integer), "PROCESSING"(String)  
DEBUG o.a.i.s.o.BaseExecutor - <==      Total: 5000  

若 Total 时间过长,可能表明 SQL 查询需要优化(如添加索引或简化条件)。


三、高级技巧:自定义日志输出格式与自动化工具

3.1 自定义 SQL 格式化输出

通过结合日志框架的格式化功能,可以更清晰地展示 SQL 语句的结构。

Logback 配置示例:

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
    <encoder>  
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>  
    </encoder>  
</appender>  

此配置将时间、线程、日志级别和内容分开展示,便于快速定位问题。


3.2 结合工具自动化分析

对于复杂项目,可使用工具(如 P6SpyMyBatis-Plus 的日志插件)增强 mybatis 打印sql 的功能。

P6Spy 配置步骤:

  1. 添加依赖:
    <dependency>  
      <groupId>p6spy</groupId>  
      <artifactId>p6spy</artifactId>  
      <version>3.9.1</version>  
    </dependency>  
    
  2. 配置 spy.properties
    module=pgjdbc  
    appender=com.p6spy.engine.spy.appender.Slf4JAppender  
    logMessageFormat=com.p6spy.engine.logging.formatter.SpyLogMessageFormat  
    

通过 P6Spy,可以捕获所有 SQL 语句并输出到日志中,甚至统计执行时间。


四、常见问题与解决方案

4.1 问题1:SQL 语句未被打印

可能原因

  • 日志级别未设置为 DEBUG
  • 日志框架未正确配置(如 Log4j 配置文件路径错误)。

解决方案
检查日志配置文件,确保 org.apache.ibatis 的日志级别为 DEBUG


4.2 问题2:参数占位符未替换为实际值

可能原因

  • 使用的日志框架不支持参数解析(如 Logback 默认不显示参数值)。

解决方案
切换到支持参数解析的框架(如 Log4j2),或在日志格式中添加参数解析配置。


结论

掌握 mybatis 打印sql 的核心技巧,能够显著提升开发和调试效率。从基础的日志配置到高级的自动化工具应用,开发者可以根据项目需求灵活选择方案。建议在日常开发中养成主动观察 SQL 日志的习惯,通过分析执行计划和参数传递,逐步优化代码的健壮性和性能。

对于初学者,建议从简单配置开始,逐步尝试复杂场景下的日志分析;中级开发者则可以结合性能分析工具,深入理解 SQL 的执行逻辑。实践是掌握这一技能的最佳途径,期待读者通过本文内容,能在实际项目中快速定位并解决相关问题。

最新发布