MyBatis 的 ++ 是按优先级顺序匹配、仅执行首个满足条件分支的动态 SQL 机制,本质为 switch-case-default 的 XML 实现,用于解决多互斥条件选一及兜底需求。

MyBatis 的 + + 是一套按优先级顺序匹配、只执行第一个满足条件分支的动态 SQL 机制,本质是 switch-case-default 的 XML 实现。
它解决的核心问题是:多个互斥条件中选其一,且必须有兜底逻辑,避免 SQL 拼接出错(比如 WHERE AND ... 这类语法错误)。
是分支容器,必须存在
- 它不带任何属性,仅作为
和的父标签 - 内部只能包含
或,不能直接写 SQL - 作用类似 Java 的
switch,控制整个分支流程的入口和边界
是条件分支,至少一个
-
test属性写 OGNL 表达式,如title != null、type == 'admin'、status == 1 && level > 5 -
从上到下逐个判断,遇到第一个为
true的就立即执行其内部 SQL,并跳出整个 - 后面所有
和都不再评估 - 相当于
if→else if→else if… 的链式结构,但更紧凑、更安全
常见写法示例:
-
AND id = #{id} -
AND username LIKE CONCAT('%', #{username}, '%') -
FROM orders_a
是默认分支,可选但强烈建议保留
- 没有
test属性,只要所有都不满足,就执行它 - 类似 Java 中的
default,起兜底作用 - 如果省略且所有条件都不成立,
块内将不生成任何 SQL —— 可能导致WHERE AND ...或FROM缺失等语法错误
例如:
<otherwise>AND is_deleted = 0</otherwise>
或更稳妥地:
<otherwise>AND 1 = 1</otherwise>
实际组合用法要点
-
通常放在或内部,避免手动拼AND/OR出错 - 多个
之间是互斥关系,不是叠加关系(区别于多个) - 条件顺序很重要:高优先级、更具体的条件往前放
-
test表达式支持完整 OGNL,可调用方法(如str.trim())、判空、比较、逻辑运算
示例片段:
<where><choose><when test="orderId != null">order_id = #{orderId}</when><when test="mobile != null and mobile != ''">user_mobile = #{mobile}</when><when test="email != null and email.matches('.+@.+')">user_email = #{email}</when><otherwise>status = 'ACTIVE'</otherwise></choose></where>
这个结构清晰表达了“优先按订单号查,不行就按手机号,再不行按邮箱(且校验格式),否则只查有效状态”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











