在IDEA中DEBUG调试时查看MyBatis-Plus动态生成的SQL语句

在IDEA中DEBUG调试时查看MyBatis-Plus动态生成的SQL语句

    • 前言:动态SQL调试的痛与解决方案
    • 一、准备工作:调试前的检查清单
    • 二、基础方法:SqlSessionTemplate断点调试
      • 步骤1:定位SqlSessionTemplate类
      • 步骤2:在invoke方法上设置断点
      • 步骤3:启动调试并触发SQL执行
      • 步骤4:查看生成的SQL语句
    • 三、MyBatis-Plus增强:特殊场景处理
      • 3.1 BaseMapper接口方法调试
      • 3.2 自定义SQL与XML混合调试
      • 3.3 条件构造器的SQL预览
    • 四、高级技巧:让调试效率翻倍
      • 4.1 使用条件断点,避免频繁暂停
      • 4.2 表达式求值,动态查看变量
      • 4.3 保存断点配置,一键复用
    • 五、避坑指南:常见问题与解决方案
      • 5.1 断点不触发怎么办?
      • 5.2 SQL语句显示不完整或有问号?
      • 5.3 调试影响性能怎么办?
    • 六、总结与扩展

前言:动态SQL调试的痛与解决方案

作为一名CRUD工程师,我们每天都在与MyBatis-Plus打交道。MP的动态SQL功能确实强大,一个LambdaQueryWrapper就能轻松搞定复杂的条件查询。但不知道你有没有遇到过这种情况:明明代码逻辑看起来没问题,可就是查不出数据,或者查询结果不符合预期。这时候如果能看到MP实际生成的SQL语句,问题可能就迎刃而解了。

今天就跟大家分享一下,如何在IDEA中通过断点调试,直观地查看MyBatis-Plus动态生成的SQL语句,以及一些实用技巧和避坑指南。亲测有效,建议收藏备用!

一、准备工作:调试前的检查清单

在开始调试之前,我们需要确保几件事:

  1. MyBatis-Plus版本:建议使用3.5.x以上版本,我目前用的是3.5.1,功能比较完善。

  2. 项目调试配置:确保你的Spring Boot项目已经配置了正确的调试启动项。在IDEA右上角的运行配置中,检查是否勾选了"Debug"模式。

  3. 依赖检查:pom.xml中需要包含MyBatis-Plus的依赖:

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version>
</dependency>
  1. 调试环境:最好使用本地开发环境,避免直接在生产/测试环境调试,以防意外。

二、基础方法:SqlSessionTemplate断点调试

这是最直接有效的方法,也是我日常开发中用得最多的方式。话不多说,直接上步骤:
在这里插入图片描述

步骤1:定位SqlSessionTemplate类

在IDEA中,按下Ctrl+N(Mac用户Cmd+O)打开类搜索框,输入SqlSessionTemplate,找到org.mybatis.spring.SqlSessionTemplate这个类。

小贴士:如果记不住完整类名,也可以只输入"SqlSession",IDEA会智能提示相关类。

步骤2:在invoke方法上设置断点

打开SqlSessionTemplate类后,找到invoke方法。这个方法是MyBatis执行SQL的关键入口。在方法名左侧的 gutter 区域点击一下,设置一个断点。

步骤3:启动调试并触发SQL执行

以调试模式启动你的应用(IDEA中点击那个绿色的小虫子图标),然后操作相关功能,触发你想要调试的SQL语句执行。

当程序执行到刚才设置的断点时,IDEA会自动暂停,进入调试视图。

步骤4:查看生成的SQL语句

根据图中的步骤一步一步往下找,就能找到MP生成的SQL语句啦

小技巧:可以将常用变量添加到监视列表,下次调试时直接查看。

三、MyBatis-Plus增强:特殊场景处理

MP相比原生MyBatis提供了更多便利功能,但在调试时也有一些特殊情况需要注意:

3.1 BaseMapper接口方法调试

当调用MP提供的BaseMapper接口方法(如selectByIdselectList等)时,断点同样会触发。但需要注意的是,MP会自动生成方法名对应的SQL,这些SQL是动态生成的,可能不在你的XML文件中。

例如调用userMapper.selectList(wrapper)时,生成的SQL会根据wrapper中的条件动态拼接。这时候查看BoundSql的sql属性,就能清晰地看到拼接后的完整SQL。

3.2 自定义SQL与XML混合调试

如果你项目中既有MP的LambdaQueryWrapper,又有自定义的XML SQL语句,调试方法是通用的。但需要注意:

  • 自定义XML中的SQL:可以直接在XML文件中点击右键,选择"Go to Declaration"跳转到对应的方法
  • 注解方式的SQL:如@Select("select * from user where id = #{id}"),可以直接在注解上设置断点

3.3 条件构造器的SQL预览

对于复杂的LambdaQueryWrapper,我有个小技巧:在代码中临时添加一行System.out.println(wrapper.getSqlSegment()),可以打印出条件部分的SQL片段。虽然不是完整SQL,但对于调试条件拼接很有帮助。

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getId, 1).like(User::getName, "张三").orderByDesc(User::getCreateTime);
// 临时添加,调试用
System.out.println("SQL条件片段:" + wrapper.getSqlSegment());
List<User> userList = userMapper.selectList(wrapper);

四、高级技巧:让调试效率翻倍

掌握了基础方法后,这些高级技巧能让你的调试效率大大提升:

4.1 使用条件断点,避免频繁暂停

如果你只想调试某个特定的SQL,可以设置条件断点:右键点击断点图标,选择"Edit Breakpoint",在Condition中输入判断条件。

例如,只想调试用户相关的SQL:

method.getName().contains("user")

或者根据SQL的ID进行过滤:

args[0].toString().contains("com.example.mapper.UserMapper.selectById")

这样只有满足条件的SQL执行时才会触发断点,避免了调试过程中频繁暂停的烦恼。

4.2 表达式求值,动态查看变量

在调试过程中,可以随时按下Alt+F8(Mac用户Option+F8)打开表达式求值窗口,输入任何你想查看的变量或表达式,IDEA会实时计算并显示结果。

比如直接输入boundSql.getSql(),就能立即看到生成的SQL,非常方便。

4.3 保存断点配置,一键复用

如果你经常需要调试SQL,可以将常用的断点配置保存起来:在Breakpoints窗口(Ctrl+Shift+F8)中,选中你设置的SQL调试断点,点击"Save"按钮,起个名字保存。下次需要时直接"Load"即可,无需重复设置。

五、避坑指南:常见问题与解决方案

5.1 断点不触发怎么办?

这是最常见的问题,可能有以下几个原因:

  1. 类路径不对:确认你断点设置的SqlSessionTemplate是项目实际使用的那个,有时候可能存在多个版本的MyBatis包。

  2. 方法没被调用:检查你的代码逻辑,确保你要调试的SQL确实被执行了。有时候可能因为条件判断导致代码没有走到。

  3. 调试模式没启动:确认你是用调试模式启动的应用,而不是普通运行模式。

  4. 断点被禁用:检查断点图标是不是灰色的(被禁用了),点击一下让它变成红色即可。

5.2 SQL语句显示不完整或有问号?

这是因为MyBatis的SQL中使用了占位符?,实际参数值需要单独查看。在BoundSql对象中,parameterObject属性就是参数值,或者查看getParameterMappings()方法的返回结果。

如果你想看到带参数的完整SQL,可以使用下面这个小工具类(我自己写的,很好用):

public class SqlUtils {public static String showSql(Configuration configuration, BoundSql boundSql) {// 实现代码略,主要功能是将?替换成实际参数值// 完整代码可以在我的GitHub上找到:https://github.com/xxx/utils}
}

5.3 调试影响性能怎么办?

长时间的调试可能会影响应用性能,特别是在循环中执行的SQL。这时候可以:

  1. 使用条件断点,只在需要时触发
  2. 调试完成后及时移除或禁用断点
  3. 避免在生产环境进行长时间调试

六、总结与扩展

掌握MyBatis-Plus动态SQL的调试技巧,能帮我们快速定位问题,提高开发效率。本文介绍的通过IDEA断点调试查看SQL的方法,是我日常工作中最常用也最有效的方式。

除了这种方法,还有一些其他工具也可以查看MyBatis生成的SQL,比如:

  • MyBatis Log Plugin:IDEA插件,能自动格式化并输出MyBatis执行的SQL
  • p6spy:一个SQL拦截器,能记录所有执行的SQL语句
  • MP的内置日志:通过配置日志级别,让MP输出执行的SQL

但这些方法要么需要额外配置,要么会输出大量日志,不如断点调试来得直接和灵活。

最后,送大家一句我很喜欢的话:“工欲善其事,必先利其器”。掌握好调试技巧,能让我们的开发之路走得更顺畅。希望本文对你有帮助,祝大家调试愉快,Bug少少!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93964.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93964.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 文本处理三剑客:awk、grep、sed 完全指南

Linux 文本处理三剑客&#xff1a;awk、grep、sed 完全指南 1. 概述 Linux 系统提供了三个强大的文本处理工具&#xff1a;awk、grep 和 sed&#xff0c;它们各有所长&#xff0c;结合使用可以高效地处理文本数据。 awk&#xff1a;擅长文本分析和格式化输出&#xff0c;是一…

pyecharts可视化图表组合组件_Grid:打造专业数据仪表盘

pyecharts可视化图表组合组件_Grid&#xff1a;打造专业数据仪表盘 目录pyecharts可视化图表组合组件_Grid&#xff1a;打造专业数据仪表盘引言图表1&#xff1a;Grid-Overlap-多X/Y轴示例代码解析1. 图表创建2. 多轴配置3. 图表重叠4. Grid布局效果与应用图表2&#xff1a;Gri…

【电气工程学习】

三极管中&#xff1a;集电极C,基极B&#xff0c;发射极E接线&#xff1a;棕正蓝负黑信号NPN开关输出的是我们的0V,也叫低电平PNP开关输出的是24V,也就是高电平&#xff08;NPN开关导通时&#xff0c;相当于把输出端“拉”到0V&#xff08;低电平&#xff09;&#xff0c;称为“…

【嵌入式】CAN通信

CAN 总线最初由博世于1980年代为汽车行业开发&#xff0c;能够简化复杂的布线网络&#xff0c;还确保可靠和安全的数据传输。 1.CAN技术解释 CAN网络中的每个节点&#xff0c;都是平等的&#xff0c;没有主次之分&#xff0c;这一点和SPI和I2C不同。每个节点都可以在需要的时…

Apache ShenYu网关与Nacos的关联及如何配合使用

Apache ShenYu 网关与 Nacos 之间的关系可以概括为 “协作互补”:Nacos 作为 服务注册与配置中心,为 ShenYu 提供动态的服务发现和配置管理能力,而 ShenYu 作为 流量网关,依赖 Nacos 实现路由信息的动态更新和实时生效。以下是详细解析: 1. 核心关系图解 拉取服务列表/路…

【CPP】一个CPP的Library(libXXXcore)和测试程序XXX_main的Demo

一个CPP的Library和测试程序Demo 1. 思路描述 目录结构 总控CMakeList.txt文件 2. Library代码实现 2.1 XXXLib.hpp文件(对外的接口定义文件)和XXXLib.cpp文件 2.1.1 XXXLib.hpp文件 2.1.2 XXXLib.cpp文件 2.2 CXXXLibApi.hpp文件和CXXXLibApi.cpp文件(内部的API基类) 2.2.1 CX…

【YashanDB认证】学习YashanDB的探索之路:从入门到实践

在国产数据库蓬勃发展的浪潮中&#xff0c;选择了YashanDB作为技术学习的切入点。这不仅让我深入了解了数据库的核心技术&#xff0c;也让我深刻体会到国产数据库在性能、可靠性和生态适配上的创新价值。以下是我在学习YashanDB过程中的经验与感悟。 一、YashanDB基础介绍 Ya…

element UI 和 element plus 在组件上有哪些不同

Element UI 和 Element Plus 都是基于 Vue 的桌面端 UI 组件库&#xff0c;由同一团队&#xff08;饿了么前端团队&#xff09;开发和维护。Element Plus 是 Element UI 的升级版&#xff0c;专为 Vue 3 设计&#xff0c;而 Element UI 仅支持 Vue 2。以下是它们在组件层面的主…

【3D重建技术】如何基于遥感图像和DEM等数据进行城市级高精度三维重建?

城市级高精度三维重建是融合多源空间数据&#xff08;遥感图像、DEM、GIS矢量等&#xff09;、计算机视觉与地理信息处理技术的复杂过程&#xff0c;核心目标是构建包含“地形地物&#xff08;建筑、道路、植被等&#xff09;”的真实、高精度三维场景。其流程可分为数据准备、…

【unitrix数间混合计算】3.4 无符号小数部分标记trait(bin_unsigned.rs)

一、源码 这段代码定义了一个类型级二进制小数系统&#xff0c;用于在编译时表示和验证二进制小数部分的有效性。 use crate::number::{F0, BFrac, Bit};/// 标记合法的二进制小数部分类型 pub trait BinFrac: Copy Default static {}// 空小数部分&#xff08;表示值为0&…

从一次 DDoS 的“死亡回放”看现代攻击链的进化

本文记录的是作者上周在测试环境真实踩到的坑。为了让读者能复现并亲手体验防御思路&#xff0c;文末给出了一份最小可运行的 Go 脚本&#xff0c;支持本地压测 日志回放&#xff0c;方便对比加防护前后的差异。攻击现场还原 周一凌晨 2:14&#xff0c;监控群里突然弹出告警&a…

LeetCode热题100--101. 对称二叉树--简单

1. 题目 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a;输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a;输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 2. 题解 /*** Definition for…

Pub/Sub是什么意思

Pub/Sub&#xff08;发布/订阅模式&#xff09;​​ 是一种异步消息通信范式&#xff0c;用于分布式系统中不同组件之间的解耦通信。它的核心思想是将消息的发送方&#xff08;发布者&#xff09;​​ 和接收方&#xff08;订阅者&#xff09;​​ 分离&#xff0c;通过一个中间…

Redisson3.14.1及之后连接阿里云redis代理模式,使用分布式锁:ERR unknown command ‘WAIT‘

文章目录一、问题背景1、问题原因2、阿里云对Redisson的支持二、解决方案1、继续使用Redisson3.14.0版本2、阿里云redis改为直连模式3、升级Redisson版本到 3.47.0一、问题背景 1、问题原因 阿里云Redis分直连和代理模式&#xff0c;其中代理模式是不支持WAIT命令的。 目前尝…

Linux: RAID(磁盘冗余阵列)配置全指南

Linux&#xff1a;RAID&#xff08;磁盘冗余阵列&#xff09;配置一、RAID 核心概念 RAID&#xff08;Redundant Array of Independent Disks&#xff0c;磁盘冗余阵列&#xff09;通过将多个物理磁盘组合为一个逻辑存储设备&#xff0c;实现提升读写性能、增强数据安全性或平衡…

《GPT-OSS 模型全解析:OpenAI 回归开源的 Mixture-of-Experts 之路》

目录 一、引言 二、GPT-OSS 模型简介 1. 版本与定位 2. 架构设计与技术亮点 2.1 Mixture-of-Experts&#xff08;MoE&#xff09;架构 2.2 高效推理机制与优化技术 2.3 模型对比 三、模型部署 1. 安装相关依赖 1.1 uv 安装 1.2 conda 安装 1.3 Transformers 运行 g…

【力扣热题100】双指针—— 接雨水

题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 注意&#xff1a;答案中不可以包含重复的三元组。输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由…

51单片机拼接板(开发板积木)

一、前言 1.1 背景 读书那会儿&#xff08;2013年左右&#xff09;网上接了很多51单片机的设计。 当时有个痛点: 每张板子都是定制的&#xff0c;画板子&#xff0c;打样&#xff0c;写代码需要花费很多时间。 希望有一张板子&#xff0c;能够实现绝大多数单片机的功能&#xf…

使用segment-anything将目标检测label转换为语义分割label

使用segment-anything将目标检测label转换为语义分割label一、segment-anything简介二、segment-anything安装2.1安装方法2.2预训练模型下载三、将目标检测label转换为语义分割label3.1示例代码3.2代码说明一、segment-anything简介 segment-anything是facebookresearch团队开…

【unitrix数间混合计算】3.3 无符号整数标记trait(bin_unsigned.rs)

一、源码 这段代码是用 Rust 语言实现的一个类型级无符号二进制整数系统&#xff0c;通过类型系统在编译时表示和操作二进制数字。这是一种典型的"类型级编程"&#xff08;type-level programming&#xff09;技术。 use crate::number::{U0, Bin, Bit, BinInt};/// …