mybatis xml 中通过 、 等标签结合 ognl 表达式实现动态 sql,推荐用 自动处理 sql 拼接与边界;复杂场景建议改用 example 或 querywrapper 构建类型安全条件。

MyBatis 在 XML 映射文件中支持多种动态条件判断方式,核心是借助 OGNL 表达式配合 `
用 标签做基础条件拼接
这是最常用的方式,适用于单个字段可选、多字段组合查询等场景。每个 `
- test 属性支持 Java 语法:`!= null`、`!= ""`、`> 0`、`.equals()`、`.contains()` 等
- 推荐搭配 `
` 标签使用,它会自动剔除开头多余的 AND/OR,并智能补上 WHERE 关键字 - 避免手动写 `WHERE 1=1`,更简洁安全
示例:
<select id="findUsers" resulttype="User">
SELECT * FROM user
<where><if test="id != null">id = #{id}</if><if test="username != null and username != ''">AND username LIKE CONCAT('%', #{username}, '%')</if><if test="status != null and status.equals('active')">AND status = #{status}</if></where></select>
用 + 实现“多选一”逻辑
类似 Java 中的 switch 或 if-else if-else,适合互斥条件(比如按不同字段模糊搜索,只生效一个)。
- 多个 `
` 顺序执行,遇到第一个为 true 的就停止后续判断 - 可选 `
` 作为兜底分支(相当于 else) - 注意 `
` 仍需包裹整个条件块,确保 SQL 合法
示例:
<select id="searchUser" resulttype="User">
SELECT * FROM user
<where><choose><when test="phone != null and phone != ''">phone = #{phone}</when><when test="email != null and email != ''">email = #{email}</when><otherwise>1 = 1</otherwise></choose></where></select>
字符串包含、区间、空值等常见判断写法
实际开发中常遇到非空校验、子串匹配、数值范围等需求,OGNL 都能直接表达:
- 判断字符串是否包含某内容:
test="name != null and name.contains('admin')" - 判断 List 是否非空:
test="ids != null and ids.size() > 0" - 判断数值在区间内:
test="age != null and age >= 18 and age (注意 <li>判空统一建议:<code>test="xxx != null and xxx != ''"(String),test="xxx != null"(对象/数字)
进阶:用 Example 或 QueryWrapper 替代 XML 手写条件
当条件逻辑特别复杂(如嵌套 AND/OR、多级关联、动态排序、分页)时,硬写 XML 易出错且难维护。此时可考虑代码层构建条件:
- TkMyBatis 的
Example:链式调用andEqualTo()、andLike()、andBetween()等 - MyBatis-Plus 的
QueryWrapper:支持 lambda 表达式,类型安全,IDE 可提示 - 优势:复用性强、单元测试友好、避免 XML 中大量重复判断逻辑
例如:
UserExample example = new UserExample();
example.createCriteria()
.andStatusEqualTo("active")
.andCreateTimeBetween(startTime, endTime);
List<user> users = userMapper.selectByExample(example);</user>











