1、批量更新
参考 https://blog.csdn.net/lu1024188315/article/details/78758943
1、更新单条记录
UPDATE course SET name = 'course1' WHEREid = 'id1';
2、更新多条记录的同一个字段为同一个值
UPDATE course SET name='course1' WHERE id in('id1','id2','id3);
3、更新多条记录为多个字段为不同的值
比较普通的写法,是通过循环,依次执行update语句。
Mybatis写法如下:
<update id="updateBatch" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update course
<set>
name=${item.name}
</set>
where id = ${item.id}
</foreach>
</update>
一条记录update一次,性能比较差,容易造成阻塞。
MySQL没有提供直接的方法来实现批量更新,但可以使用 case when
语法来实现这个功能。
UPDATE course
SET name = CASE id
WHEN 1 THEN 'name1'
WHEN 2 THEN 'name2'
WHEN 3 THEN 'name3'
END,
title = CASE id
WHEN 1 THEN 'New Title 1'
WHEN 2 THEN 'New Title 2'
WHEN 3 THEN 'New Title 3'
END
WHERE id IN (1,2,3)
这条sql的意思是,如果id为1,则name的值为name1,title的值为New Title1;依此类推。
在Mybatis中的配置则如下:
<updateid="updateBatch"parameterType="list">
update course
<trim prefix="set" suffixOverrides=",">
<trim prefix="name=case" suffix="end,">
<foreach collection="list" item="item" index="index">
<if test="item.name!=null">
when id=#{item.id} then #{item.name}
</if>
</foreach>
</trim>
<trim prefix="title =case" suffix="end,">
<foreach collection="list" item="item" index="index">
<if test="item.title!=null">
when id=#{item.id} then #{item.title}
</if>
</foreach>
</trim>
</trim>
where
<foreach collection="list" separator="or" item="item" index="index">
id=#{item.id}
</foreach>
</update>
< trim > 属性说明
- prefix,suffix 表示在 trim 标签包裹的部分的前面或者后面添加内容
- 如果同时有 prefixOverrides,suffixOverrides 表示会用 prefix,suffix 覆盖 Overrides 中的内容。
- 如果只有 prefixOverrides,suffixOverrides 表示删除开头的或结尾的 xxxOverides 指定的内容。
如果 对要更新的数据进行判断,只有符合条件的数据才能进行更新,这种情况可以这么做:
<trim prefix="status =case" suffix="end,">
<foreach collection="list" item="item" index="index">
<if test="item.status !=null and item.status != -1">
when id=#{item.id} then #{item.status}
</if>
</foreach>
</trim>
这样的话只有要更新的 list 中 status != null && status != -1 的数据才能进行 status 更新.其他的将使用默认值更新
,而 不会保持原数据不变
.如果要保持原数据不变呢?即满足条件的更新,不满足条件的保持原数据不变,简单的来做就是再加一个 < if > ,因为 mybatis 中 没有 if...else...
语法,但可以通过多个 < if > 实现同样的效果
,如下:
<trim prefix="status =case" suffix="end,">
<foreach collection="list" item="item" index="index">
<if test="item.status !=null and item.status != -1">
when id=#{item.id} then #{item.status}
</if>
<if test="item.status == null or item.status == -1">
when id=#{item.id} then mydata_table.status //这里就是原数据
</if>
</foreach>
</trim>
非trim的另外一个示例:
<update id = "updateBatch" parameterType = "java.util.List" >
update mydata_table
set status=
<foreach collection="list" item="item" index="index"
separator=" " open="case ID" close="end">
when #{item.id} then #{item.status}
</foreach>
where id in
<foreach collection="list" index="index" item="item"
separator="," open="(" close=")">
#{item.id,jdbcType=BIGINT}
</foreach>
</update>
其中 when…then… 是 sql 中的 “switch” 语法。这里借助 mybatis 的 < foreach > 语法来拼凑成了批量更新的 sql ,上面的意思就是批量更新 id 在 updateBatch 参数所传递 List 中的数据的status 字段。还可以使用 < trim > 实现同样的功能,代码如下:
<update id="updateBatch" parameterType="java.util.List">
update mydata_table
<trim prefix="set" suffixOverrides=",">
<trim prefix="status =case" suffix="end,">
<foreach collection="list" item="item" index="index">
when id=#{item.id} then #{item.status}
</foreach>
</trim>
</trim>
where id in
<foreach collection="list" index="index" item="item" separator="," open="(" close=")">
#{item.id,jdbcType=BIGINT}
</foreach>
</update>
其结构如下:
update mydata_table
set status =
case
when id = #{item.id} then #{item.status}//此处应该是<foreach>展开值
...
end
where id in (...);
2、批量新增
批量插入sql:
insert table () values (),(),()
批量插入xml:
<insert id="insertBatch" parameterType="java.util.List">
INSERT INTO table (creat_time, modified_time, name, code)
VALUES
<foreach collection="list" item="item" index="index" separator=",">
(now(), now(),
#{item.name,jdbcType=INTEGER}, #{item.code,jdbcType=BIGINT})
</foreach>
</insert>