mybatis动态sql的核心价值在于根据参数动态生成合法sql。通过处理多条件查询、实现单选分支、支持部分字段更新、安全执行批量操作,避免拼接错误与sql注入。

MyBatis 动态 SQL 的核心价值,是让 SQL 语句能“看参数脸色行事”——参数有值就加条件,没值就跳过,不拼错、不报错、不注入。关键不是写多少标签,而是用对场景、理清逻辑。
多条件查询:用 + 避免 AND 开头或空 WHERE
用户搜索时,姓名、状态、时间范围可能全填,也可能只填一个。手动拼接容易出现 WHERE AND name = ? 这类语法错误。<where></where> 会自动:
• 忽略所有 <if></if> 中未满足的条件
• 去掉第一个有效条件前多余的 AND/OR
• 整个条件块为空时,自动省略 WHERE 关键字
<if test="name != null and name != ''">AND name LIKE CONCAT('%', #{name}, '%')</if><if test="status != null">AND status = #{status}</if><if test="startTime != null and endTime != null">AND create_time BETWEEN #{startTime} AND #{endTime}</if>
单选分支查询:用 + + 实现互斥逻辑
当多个条件不能共存(比如“按ID查”“按手机号查”“按用户名查”,三者只走其一),<choose></choose> 就比堆砌多个 <if></if> 更清晰。它按顺序匹配第一个为 true 的 <when></when>,其余跳过;都不满足则执行 <otherwise></otherwise>。
<when test="id != null and id > 0">AND id = #{id}</when><when test="phone != null and phone != ''">AND phone = #{phone}</when><otherwise>AND is_deleted = 0</otherwise>
部分字段更新:用 + 自动剔除末尾逗号
表单编辑提交时,往往只改了几个字段。若用静态 SQL,就得为每种组合写一个 update 方法。<set></set> 会:
• 自动添加 SET 关键字
• 只保留有值的字段赋值语句
• 删除最后多余的逗号
<set></set><if test="username != null">username = #{username},</if><if test="email != null">email = #{email},</if><if test="status != null">status = #{status}</if>
批量操作与 IN 查询:用 安全生成列表参数
查多个 ID、删一批记录、插入多条数据,都离不开循环。直接拼字符串易出错且危险。<foreach></foreach> 支持 collection、array、map 等入参类型,自动处理占位符和分隔符。
- IN 查询:
AND id IN <foreach item="id" collection="idList" open="(" separator="," close=")">#{id}</foreach> - 批量插入:
INSERT INTO user (name, age) VALUES <foreach ...> (#{item.name}, #{item.age})</foreach> - 注意:collection 属性名取决于传参方式(如 List 参数默认是 list,Map 中需指定 key)











