表结构:
drop table if exists `t_user`;
create table `t_user`(
`id` bigint(20) not null auto_increment comment '主键id',
`name` varchar(32) not null default '' comment '姓名',
`phone` varchar(32) not null default '' comment '手机',
`create_time` datetime not null default current_timestamp comment '创建时间',
`update_time` datetime not null default current_timestamp on update current_timestamp comment '更新时间',
primary key (`id`),
unique key `phone` (`phone`),
key `name` (`name`)
) engine=innodb auto_increment=1000 default charset=utf8mb4 comment='用户表';
一、多条update语句模式
注意需要开启批量执行sql参数allowMultiQueries,参考MySQL中jdbc驱动开启批量执行sql参数allowMultiQueries
XML文件:
<update id="batchUpdate">
<foreach collection="list" item="item">
update t_user
set
`name` = #{item.name},
`phone` = #{item.phone},
`create_time` = #{item.createTime},
`update_time` = #{item.updateTime}
where id = #{item.id};
</foreach>
</update>
执行样例SQL:
update t_user set `name` = 'a8adecfd-f050-4c23-ad97-11c037b1', `phone` = 'b2802f1f-2119-49b3-a867-b3f71672', `create_time` = '2023-12-04 16:08:22.291', `update_time` = '2023-12-04 16:08:22.291' where id = 1000;
update t_user set `name` = '063911e5-951c-4f14-8729-75b91d23', `phone` = '5e305d67-9061-42ad-b9bf-13ba8fed', `create_time` = '2023-12-04 16:08:22.291', `update_time` = '2023-12-04 16:08:22.291' where id = 1001;
update t_user set `name` = 'ac3e69c6-def8-4e5c-9b99-6e4bbd13', `phone` = 'a665aec2-876f-42cd-a64a-02d89cc8', `create_time` = '2023-12-04 16:08:22.291', `update_time` = '2023-12-04 16:08:22.291' where id = 1002;
二、on duplicate key update模式
即插入数据,插入失败时(主键或唯一键冲突)则进行更新,实现有则更新无则插入,参考MySQL下使用on duplicate key update实现“有则更新,无则新增”操作
XML文件:
<insert id="batchUpdateOnDuplicateKey">
insert into t_user (id, `name`, `phone`, `create_time`, `update_time`)
values
<foreach collection="list" item="item" separator=",">
(
#{item.id},
#{item.name},
#{item.phone},
#{item.createTime},
#{item.updateTime}
)
</foreach>
on duplicate key update
`name` = values(`name`),
`phone` = values(`phone`),
`create_time` = values(`create_time`),
`update_time` = values(`update_time`)
</insert>
执行样例SQL:
insert into t_user (id, `name`, `phone`, `create_time`, `update_time`)
values
( 1000, 'f6be36f4-6ef1-4b66-b0a7-e1ea1330', '65b22575-2e89-4df3-bd8b-c8ea2ace', '2023-12-04 16:10:43.529', '2023-12-04 16:10:43.529' ) ,
( 1001, 'b82083d8-b2ca-4a6f-b49d-b6c024b5', '99359904-8f42-4337-a319-0c1deb0c', '2023-12-04 16:10:43.529', '2023-12-04 16:10:43.529' ) ,
( 1002, '667a371d-00aa-4146-b342-5e9300d3', 'd15aeda4-4fb4-472d-9903-a020a61f', '2023-12-04 16:10:43.529', '2023-12-04 16:10:43.529' )
on duplicate key update
`name` = values(`name`),
`phone` = values(`phone`),
`create_time` = values(`create_time`),
`update_time` = values(`update_time`)
三、case when模式
相当于在sql中写if语句,缺点是sql会比较长。
XML文件:
<update id="batchUpdateCaseWhen">
update t_user
set
`name` = case
<foreach collection="list" item="item">
when id = #{item.id} then #{item.name}
</foreach>
end,
`phone` = case
<foreach collection="list" item="item">
when id = #{item.id} then #{item.phone}
</foreach>
end,
`create_time` = case
<foreach collection="list" item="item">
when id = #{item.id} then #{item.createTime}
</foreach>
end,
`update_time` = case
<foreach collection="list" item="item">
when id = #{item.id} then #{item.updateTime}
</foreach>
end
where id in
<foreach collection="list" item="item" separator="," open="(" close=")">
#{item.id}
</foreach>
</update>
执行样例SQL:
update
t_user
set
`name` = case
when id = 1000 then 'd7242b1f-3539-49e8-96c8-1cf4c365'
when id = 1001 then 'e84725b8-a221-4509-b892-e5ed7f9f'
when id = 1002 then '60cce924-448e-4225-807f-970d6517'
end,
`phone` = case
when id = 1000 then '52ac7cf4-6ca5-455f-b982-b05c571e'
when id = 1001 then 'b9cac4e2-0be9-4252-9cfb-d23da75e'
when id = 1002 then 'eb7ca69d-be5b-4212-b290-58e62eec'
end,
`create_time` = case
when id = 1000 then '2023-12-04 16:12:21.881'
when id = 1001 then '2023-12-04 16:12:21.881'
when id = 1002 then '2023-12-04 16:12:21.881'
end,
`update_time` = case
when id = 1000 then '2023-12-04 16:12:21.881'
when id = 1001 then '2023-12-04 16:12:21.881'
when id = 1002 then '2023-12-04 16:12:21.881'
end
where
id in ( 1000 , 1001 , 1002 )
四、join模式
相当于查一个临时表出来去join欲更新的表,然后映射更新数据。
XML文件:
<update id="batchUpdateJoin">
update t_user m join (
<foreach collection="list" item="item" separator="union all">
select #{item.id} as id, #{item.name} as `name`, #{item.phone} as `phone`, #{item.createTime} as `create_time`, #{item.updateTime} as `update_time`
</foreach>
) t using(id)
set
m.`name` = t.`name`,
m.`phone` = t.`phone`,
m.`create_time` = t.`create_time`,
m.`update_time` = t.`update_time`
where m.id in
<foreach collection="list" item="item" separator="," open="(" close=")">
#{item.id}
</foreach>
</update>
执行样例SQL:
update t_user m join
(
select 1000 as id, '7854c1e4-7f22-4de3-9304-825e4ab7' as `name`, 'b9ce7be2-8c43-4ee2-ab6b-0b26833c' as `phone`, '2023-12-04 16:16:41.127' as `create_time`, '2023-12-04 16:16:41.127' as `update_time`
union all
select 1001 as id, '93334332-6197-4820-a1ab-932bd066' as `name`, 'e2baef75-6818-498f-bf62-a8780e9a' as `phone`, '2023-12-04 16:16:41.127' as `create_time`, '2023-12-04 16:16:41.127' as `update_time`
union all
select 1002 as id, 'b20d40b5-e719-4b81-b453-943aad82' as `name`, '701a6a51-b7e4-4314-8345-2661e7e0' as `phone`, '2023-12-04 16:16:41.127' as `create_time`, '2023-12-04 16:16:41.127' as `update_time`
) t using(id)
set
m.`name` = t.`name`,
m.`phone` = t.`phone`,
m.`create_time` = t.`create_time`,
m.`update_time` = t.`update_time`
where m.id in ( 1000 , 1001 , 1002 )