工作中遇到批量更新的场景其实是比较常见的。
但是该如何正确的进行批量update,很多时候往往有点头大。
这里列2种可用的方式,供选择(请选择方式一,手动狗头。)。
如果使用了mybatis增强组件mybatisplus,可以参考官网给出的解决方式(updatebatchbyid),或者自己查一下。
批量update方式一:sql内foreach
举个🌰
<update id="updateuserforbatch" parametertype="com.bees.srx.entity.userentity">
<foreach collection="list" item="entity" separator=";">
update sys_user
set password=#{entity.password},age=#{entity.age}
<where>
id = #{entity.id}
</where>
</foreach>
</update>
这样写,肯定比 在业务方法中for循环单条update的效率是要高的。
但是如果遇到大批量的更新动作,可能也会产生效率低下的问题。
原因是sql内的foreach本质上还是循环插入每一条数据,会产生list.size()个单条插入的独立sql语句,每一条 update 语句都会被单独发送到数据库服务器执行。
这意味着如果列表中有100个元素,就会产生100次数据库往返通信。
这种方式不仅效率低下,而且对于大型批处理操作来说,可能会导致性能瓶颈和资源浪费。
优化:通过jdbc批处理通过 mybatis 的 sqlsession 提供的批处理功能来手动执行批量更新。
try (sqlsession session = sqlsessionfactory.opensession(executortype.batch)) {
usermapper mapper = session.getmapper(usermapper.class);
for (userentity user : userlist) {
mapper.updateuser(user);
}
session.commit();
}
这里mapper.updateuser就是单条的update语句。
通过这种方式,mybatis 会在内存中积累所有的更新命令,然后在调用session.commit() 时一次性提交给数据库,这比逐条执行要高效得多。
注意:是否存在效率差异,未实践过!!!可能存在误人子弟的嫌疑。
批量update方式二:insert + on duplicate key update
<update id="updateforbatch" parametertype="com.bees.srx.entity.userentity">
insert into sys_user
(id,username,password) values
<foreach collection="list" index="index" item="item" separator=",">
(#{item.id},
#{item.username},
#{item.password})
</foreach>
on duplicate key update
password=values(password)
</update>
不建议使用。要求较多,而且容易出现死锁。
注意事项
- 唯一键约束:确保 sys_user 表中的 id 字段有唯一键约束(通常是主键)。如果 id 不是唯一的,on duplicate key update 将不会触发更新操作。
- 性能:这种方式在大数据量的情况下比多次单独的 insert 和 update 操作要高效得多。
- 事务管理:确保这个操作在一个事务中执行,以保证数据的一致性。如果中间发生错误,可以回滚整个操作。
- 字段顺序:确保 values 函数中的字段顺序与 on duplicate key update 子句中的字段顺序一致。
总结:
建议使用方式一,或者其优化方式(jdbc批处理)。
到此这篇关于mysql批量update的两种方式小结的文章就介绍到这了,更多相关mysql批量update内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论