MyBatis 的 <if> 和 <where> 标签配合可安全动态拼接SQL条件:<if> 通过OGNL表达式控制条件生效,<where> 自动添加WHERE并去除首个多余AND/OR;需避免手动写WHERE或外部AND,基本类型参数应包装为包装类或用@Param注解。
` 和 `
MyBatis 的 `
用 `` 控制单个条件是否生效
`
常见写法示例:
- 判断字符串非空且非空白:
test="username != null and username.trim() != ''" - 判断数值型字段有值(如不为 0 或 null):
test="age != null and age > 0" - 判断 List 非空:
test="ids != null and !ids.isEmpty()" - 注意:OGNL 中
==和eq都可用,但推荐用==;字符串比较用!=而非ne更直观
用 `` 自动处理 WHERE 关键字和前置 AND/OR
`WHERE,并**自动去除第一个条件前多余的 AND 或 OR**。
立即学习“Java免费学习笔记(深入)”;
例如:
<where>
<if test="username != null and username.trim() != ''">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="status != null">
AND status = #{status}
</if>
</where>
若只有 status 有值,生成的 SQL 是:WHERE status = ?;若两个都有值,则是:WHERE username LIKE ... AND status = ?——无需担心开头多出 AND。
避免常见陷阱
以下写法容易出错,需特别注意:
-
不要在 `
` 内部写 WHERE :`` 已负责加 WHERE,重复写会导致语法错误 -
不要把 AND 放在 `
` 外面 :比如写成AND <if test="...">...</if>,这样当 if 不生效时,AND 会残留,导致 SQL 报错 -
多个 `
` 并列时,统一用 AND 连接即可**(推荐)** :`` 会自动清理首个 AND;若需 OR 逻辑,可改用 ` ` 配合 ` ` 手动控制 - 参数为基本类型(如 int)时,null 判断无效:应包装为 Integer,或改用 `@Param` 注解明确命名,再在 test 中用 `_parameter` 访问原始值(不推荐,可读性差)
进阶技巧:组合条件 + 排序/分页动态控制
除了 WHERE 条件,`
例如按字段排序:
<trim prefix="ORDER BY" suffixOverrides=","> <if test="orderByField == 'username'">username ASC,</if> <if test="orderByField == 'createTime'">create_time DESC,</if> </trim>
或者更稳妥地用 `


















