1. 前置基础: <if> 标签
大多数动态标签都需要结合 <if> 进行条件判断。
java
<if test="name != null and name != ''">
AND name = #{name}
</if>
2. <where> 标签:智能处理 AND/OR 与 WHERE 关键字
作用
用于封装查询条件。
-
自动插入
WHERE关键字(如果内部有满足条件的内容)。 -
智能去除 内部 SQL 语句开头多余的
AND或OR。
java
<select id="findUser" resultType="User">
select * from user
<where>
<if test="name != null">
name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
3. <set> 标签:智能处理逗号与 SET 关键字
作用
用于更新操作。
-
自动插入
SET关键字。 -
智能去除 最后一个字段后面多余的逗号
,。
场景:避免更新语句多余的逗号
java
<update id="updateUser">
update user
<set>
<if test="name != null">
name = #{name},
</if>
<if test="age != null">
age = #{age},
</if>
<if test="email != null">
email = #{email},
</if>
</set>
where id = #{id}
</update>
4. <foreach> 标签:遍历集合(批量操作/IN 查询)
作用
用于遍历数组、List、Map 等集合,通常用于 IN 查询或批量插入。
属性说明
| 属性 | 描述 |
|---|---|
collection |
遍历的集合名称(传入的 List/Array/Map 的 Key) |
item |
当前遍历元素的别名 |
index |
当前索引(List 中是索引,Map 中是 Key) |
open |
遍历开始拼接的符号(通常是 () |
close |
遍历结束拼接的符号(通常是 )) |
separator |
元素之间的分隔符(通常是 ,) |
in条件查询:
java
<select id="selectByIds" resultType="User">
select * from user
<where>
id IN
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</where>
</select>
批量插入
java
<insert id="batchInsert">
insert into user (name, age) values
<foreach collection="list" item="item" separator=",">
(#{item.name}, #{item.age})
</foreach>
</insert>
- 当遍历
List或数组时,index的类型是int;遍历Map时,index的类型是Object(与键的类型一致)。
在批量插入中,利用 index 给每个元素加上序号(如生成复合键)
java
<insert id="batchInsertWithOrder">
insert into user_order (user_id, order_seq, product_name) values
<foreach collection="list" item="item" index="idx" separator=",">
(#{item.userId}, #{idx}, #{item.productName})
</foreach>
</insert>
假设传入的 list 包含三个订单项,生成的 SQL 大致为:
java
insert into user_order (user_id, order_seq, product_name) values
(100, 0, '手机'),
(100, 1, '充电器'),
(100, 2, '耳机')
遍历 Map 时,index 取出键(Key)item :表示 Map 中每个键值对的 值(Value)
java
<select id="selectByMap" resultType="User">
select * from user where
<foreach collection="params" item="value" index="key" separator="AND">
${key} = #{value}
</foreach>
</select>
如果 params 是一个 Map:{"name": "张三", "age": 25},生成的 SQL 是
java
select * from user where name = ? AND age = ?
5. <trim> 标签:万能前缀/后缀处理器
<where> 和 <set> 本质上是 <trim> 的特殊实现。如果遇到更复杂的拼接需求,可以直接使用 <trim>。
属性说明
-
prefix:在 SQL 片段前面加上指定内容。 -
suffix:在 SQL 片段后面加上指定内容。 -
prefixOverrides:去掉 SQL 片段前面指定的多余内容。 -
suffixOverrides:去掉 SQL 片段后面指定的多余内容。
模拟 <where> 标签
java
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
自定义场景:拼接 values 时去除括号前的逗号
java
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">name,</if>
<if test="age != null">age,</if>
</trim>
6. <choose> (when/otherwise) :类似 Switch 语句
当需要"多选一"的逻辑时使用(只要第一个满足条件的,后面的忽略)。
java
<select id="findActiveUser" resultType="User">
select * from user
<where>
<choose>
<when test="name != null">
AND name = #{name}
</when>
<when test="age != null">
AND age = #{age}
</when>
<otherwise>
AND status = 'ACTIVE'
</otherwise>
</choose>
</where>
</select>
7. <bind> :绑定变量
用于模糊查询,防止 SQL 注入,或复用变量表达式。
java
<select id="selectUser" resultType="User">
<bind name="pattern" value="'%' + name + '%'"/>
select * from user where name like #{pattern}
</select>