set 更新字段
<set> 标签是 UPDATE 语句的专用动态标签,自动添加 SET 关键字并移除末尾多余的逗号,实现选择性字段更新。
基本语法
XML
<set>
<!-- 动态更新字段 -->
</set>
选择性更新
仅更新传入的字段,其他字段保持原值:
XML
<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>
<if test="status != null">status = #{status},</if>
</set>
WHERE id = #{id}
</update>
传入 name="张三", age=null, email="new@test.com" 时:
SQL
UPDATE user SET name = ?, email = ? WHERE id = ?
末尾逗号被自动移除。
等效 trim 配置
<set> 等价于:
XML
<trim prefix="SET" suffixOverrides=",">
<!-- 动态更新字段 -->
</trim>
set 是 trim 的封装,仅处理后缀逗号移除,不处理前缀移除。
结合主键条件
XML
<update id="updateSelective">
UPDATE user
<set>
<if test="name != null">name = #{name},</if>
<if test="age != null">age = #{age},</if>
<if test="updateTime != null">update_time = NOW()</if>
</set>
WHERE id = #{id}
</update>
最后一个字段后不加逗号,避免多余逗号出现在末尾。
与 bind 配合
XML
<update id="updateUserWithHistory">
<bind name="now" value="@java.time.LocalDateTime@now()"/>
UPDATE user
<set>
<if test="name != null">name = #{name},</if>
<if test="version != null">version = #{version},</if>
update_time = #{now}
</set>
WHERE id = #{id}
</update>
全部字段为空的处理
所有 if 都不满足时,SET 内部为空,会生成非法 SQL:
SQL
UPDATE user WHERE id = ?
-- 缺少 SET 子句,SQL 报错
解决方案:添加 alwaysUpdate 兜底:
XML
<update id="updateUser">
UPDATE user
<set>
<if test="name != null">name = #{name},</if>
<if test="age != null">age = #{age},</if>
update_time = NOW()
</set>
WHERE id = #{id}
</update>
至少保留一个必更字段(如 update_time),避免 set 内部全空。
批量更新
XML
<update id="batchUpdateStatus">
UPDATE user
<set>
status = #{status},
update_time = NOW()
</set>
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
注意事项
- set 仅移除末尾逗号,不移除开头逗号,每个字段后必须加逗号(最后一个可选)
- set 内部全为空时生成非法 SQL,需至少保留一个必更字段
- set 不处理前缀覆盖(如移除首个 AND),仅处理后缀逗号
- 与 where 不同:where 移除首个 AND/OR,set 移除末尾逗号
要点总结
- set 自动添加 SET 关键字并移除末尾多余逗号
- 适用于选择性字段更新,避免全量覆盖
- 等效于
<trim prefix="SET" suffixOverrides=","> - set 内部不能全空,至少保留一个必更字段(如 update_time)
- 每个字段后加逗号,最后一个可选,set 自动处理末尾裁剪
📝 发现内容有误?点击此处直接编辑