温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

动态SQL怎么调试

发布时间:2026-07-14 09:15:16 来源:亿速云 阅读:86 作者:小樊 栏目:数据库

动态 SQL 的“调试难”主要是因为 SQL 是在运行时才拼出来的,不像静态 SQL 一眼就能看到。下面按常见场景 + 实用调试方法系统讲一下,基本能覆盖 90% 的情况。


一、先明确:你用的是哪种动态 SQL?

不同技术栈,调试方式不一样:

场景 常见技术
MyBatis <if>/<choose>/<foreach>
JDBC / 原生代码 字符串拼接 SQL
Spring JPA Specification、Criteria
存储过程 PL/SQL / T-SQL
自己拼 SQL String.format、StringBuilder

下面重点讲 最常见、最坑的 MyBatis 动态 SQL


二、MyBatis 动态 SQL 调试(重点)

✅ 方法 1:打开 MyBatis SQL 日志(最关键)

1️⃣ 打印最终执行的 SQL

application.yml / application.properties 中:

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

或者(推荐,配合日志框架):

logging:
  level:
    com.xxx.mapper: debug

执行后你会看到类似:

==>  Preparing: SELECT * FROM user WHERE 1=1 AND age > ? AND name = ?
==> Parameters: 18(Integer), Tom(String)

这已经是“最终 SQL”了


✅ 方法 2:把 ? 替换成真实参数(人工还原)

MyBatis 默认是 预编译 SQL + 参数占位符,你可以手动还原:

SELECT * FROM user WHERE age > 18 AND name = 'Tom'

⚠️ 注意:

  • 字符串要加引号
  • 日期、NULL 要特别小心

✅ 方法 3:在 Mapper 中打印参数(快速定位)

System.out.println(userQuery);

或:

log.debug("query param: {}", userQuery);

确认:

  • 参数是否为 null
  • 集合是否为空
  • 条件是否真的成立

✅ 方法 4:把动态 SQL 拷出来单独执行

这是最实用的调试方式之一

  1. 从日志里复制 SQL
  2. 到数据库客户端(Navicat / DataGrip / DBeaver)
  3. 直接执行

如果这里就报错:

  • ✅ SQL 问题
  • ❌ 不是 MyBatis 问题

✅ 方法 5:用 <script> + 注解方式时特别小心

@Select("<script>
  SELECT * FROM user
  <where>
    <if test='name != null'> AND name = #{name} </if>
  </where>
</script>")

调试建议:

  • 先改成 XML
  • XML 更容易看清楚结构

✅ 方法 6:MyBatis 动态 SQL 常见坑(重点)

❌ 1. <if test="list != null"> 但 list 为空

<if test="ids != null and ids.size() > 0">

✅ 正确写法


❌ 2. 字符串判断错误

<if test="type == 'A'">   <!-- 错误 -->

✅ 正确:

<if test='type == "A"'>

或:

<if test="type.equals('A')">

❌ 3. 多了一个 AND / OR

WHERE
<if test="name != null">AND name = #{name}</if>

✅ 用 <where> 标签:

<where>
  <if test="name != null">AND name = #{name}</if>
</where>

三、JDBC / 自己拼 SQL 的调试方式

✅ 1. 打印最终 SQL(最重要)

System.out.println(sql);

✅ 2. 避免直接拼接参数(安全 + 好调试)

❌ 错误:

"WHERE name = '" + name + "'"

✅ 正确:

"WHERE name = ?"

四、数据库层调试(通用)

✅ 1. 开启数据库日志

MySQL

SHOW VARIABLES LIKE 'general_log';
SET GLOBAL general_log = ON;

PostgreSQL

SELECT * FROM pg_stat_activity;

五、调试动态 SQL 的“黄金流程”

90% 问题按这个流程都能解决

  1. ✅ 打开 SQL 日志
  2. ✅ 把 ? 替换成真实值
  3. ✅ 在数据库客户端执行
  4. ✅ 检查参数是否为 null / 空
  5. ✅ 检查 <if> 条件是否真的成立

六、如果你愿意,我可以帮你“现场调试”

你可以直接贴:

  • ✅ Mapper XML
  • ✅ Mapper 接口方法
  • ✅ 传入的参数对象
  • ✅ 报错信息或错误 SQL

我可以 直接帮你指出哪一行拼错了、为什么条件没生效

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI