在 动态 SQL 中处理“空值(NULL)”是一个非常常见、也很容易踩坑的问题。不同技术栈处理方式略有差异,但核心思想一致:区分“未传条件”和“传了空值”,并据此决定是否拼接 SQL。
下面按常见场景系统说明。
NULL ≠ 空字符串
NULL 表示“没有值”'' 是一个“有值的值”动态 SQL 的目标
判断顺序很重要
是否传参?
├─ 没传 → 不拼
└─ 传了 → 再判断是否为 NULL
<select id="queryUser" resultType="User">
SELECT * FROM user
WHERE 1 = 1
<if test="name != null and name != ''">
AND name = #{name}
</if>
<if test="status != null">
AND status = #{status}
</if>
</select>
✅ 要点:
!= null and != ''!= null 即可如果前端 明确传了 NULL,想查 status IS NULL:
<if test="status == null">
AND status IS NULL
</if>
⚠️ 注意:
status = null 在 SQL 中是 永远不成立 的。
public class UserQuery {
private String name; // null = 未传
private Boolean queryNull; // true = 我要查 NULL
}
<if test="queryNull != null and queryNull">
AND status IS NULL
</if>
<if test="status != null">
AND status = #{status}
</if>
✅ 这是最严谨的写法
AND status = #{status}
当 status 为 NULL 时:
status = null ❌<choose>
<when test="status == null">
AND status IS NULL
</when>
<otherwise>
AND status = #{status}
</otherwise>
</choose>
sql += " AND status = " + status;
if (status != null) {
sql += " AND status = ?";
} else {
sql += " AND status IS NULL";
}
SELECT * FROM user
WHERE COALESCE(status, 0) = 0;
⚠️ 会导致索引失效,不推荐用于大表
| 问题 | 说明 |
|---|---|
= NULL |
❌ 永远不成立 |
| 空字符串当 NULL | ❌ 逻辑错误 |
| 不区分“未传”和“NULL” | ❌ 查询条件错 |
| 动态 SQL 不判空 | ❌ SQL 语法错误 |
动态 SQL 处理空值的核心:
先判断“参数是不是存在”,再决定是拼= ?还是IS NULL,永远不要用= NULL。
如果你用的是 MyBatis / JPA / Spring Data / 某个具体数据库(Oracle / MySQL),可以告诉我,我可以给你更贴近你项目的示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。