mybatis批量更新及其效率问题
mybatis批量更新及其效率问题
最近,负责公司⼀些旧数据的批量整理和清洗⼯作,在⽹上寻了两种mybatis批量更新的⽅法。现在在这⾥总结下和说明下遇到的问题。
⼀:背景
公司旧数据的清洗,⽐如图⽚路径的改变,⽇期格式的改变(⽇期格式是varchar),因为数据⼤体上有⼀定的规律可寻,所以我的解决思路是⽤mybatis操作数据库,把需要清洗的数据查询出来并按⼀定规律进⾏清洗,在批量更新进数据库中。在这⾥尝试了两种⽅式的批量更新。
注意:
public void updateData(List<Map<String, Object>> map);
1.这条批量更新的传⼊参数是⼀个List<Map<String, Object>> map。
url: jdbc:mysql://localhost:3306/task?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&allowMultiQueries=true
2.jdbc与mysql的连接的url中要添加allowMultiQueries=true参数。本⼈因为刚开始没有加这个参数,导致⼀直报错。
### Error updating database. Cause: sql.ptions.PacketTooBigException: Packet for query is too large (12,981,868 > 4,194,304)
这是因为mysql数据库限制了处理⽂件的⼤⼩,默认是4MB,修改即可。
修改⽅法:
第⼀种:
在mysql的配置⽂件my.ini中添加 max_allowed_packet =67108864 ,我这⾥设置的是64MB,各位可以按照需要⾃⾏设置,这种⽅法是修改配置⽂件,所以就算数据库重启也会⽣效。
第⼆种:
set global max_allowed_packet = 64*1024*1024;
执⾏此sql语句可以把⽂件处理的最⼤值设置为64MB,需要多少⾃⾏决定,这种⽅式修改,数据库重启之后会重置为默认值。
show VARIABLES like '%max_allowed_packet%';
这个sql语句是查询⽂件处理的最⼤值是多少。
⼆:批量更新的⽅式总结:
第⼀种:
<update id="updata1">
<foreach collection="list" item="item" separator=";">
update refund_assistant_stqd set images=#{item.images} where id=#{item.id}
</foreach>
</update>
这种⽅法会⽣成这样的语句:
update refund_assistant_stqd set images=#{item.images} where id=#{item.id};
update refund_assistant_stqd set images=#{item.images} where id=#{item.id};
......
这样与在java代码⾥⾯循环做⼀个循环没有啥本质上区别,根本就不是批量操作。也使⽤过了。效率极其之低,并且对数据库的负载相当之⼤,运⾏期间磁盘IO达到了百分之百,这种⽅法是不可取的,望后⾯的⼈能警醒。
第⼆种:
<update id="updateData">
update refund_assistant_stqd
<trim prefix="set" suffixOverrides=",">
<trim prefix="images =case" suffix="end,">
<foreach collection="list" item="item" index="index">
when id=#{item.id} then #{item.images}
批量更新sql语句</foreach>
</trim>
</trim>
where id in
<foreach collection="list" index="index" item="item" separator="," open="(" close=")">
#{item.id}
</foreach>
</update>
这种⽅法会⽣成这样的语句:
update refund_assistant_stqd set
images= (case when id=##{item.id} then #{item.images}),
images= (case when id=##{item.id} then #{item.images}),
.....
where id in (#{item.id},#{item.id},...)
这种⽅法采⽤了case when 机制,使得相应的id与images能相匹配,只⽣成了⼀条sql语句,所以对数据库的压⼒会⼤⼤的缩⼩,时间都会花费在sql字符串的拼接上,并且sql的拼接是在你的电脑上完成的,不会对远程数据库的服务器产⽣不必要的负载。效率提⾼了很多。本⼈更新了12万条数据⽤了367秒,上⾯的第⼀种⽅法运⾏了20分钟之后我就放弃了,所以并没有测试出时间。
三:总结:
解决完以上背景⾥⾯的注意事项之后,本⼈的任务就执⾏完成了。
在这⾥要说⼀下,mybatis的批量操作原理就是使⽤sql 字符串的拼接技术,了解其原理之后对mybatis的批量操作处理有了⼀个⼤概轮廓了,不再神秘,所以,我们学习技术不仅仅要知其然,更要知其所以然。
这是⼩编正式写博客的第⼀篇,⼩编刚毕业⼯作半年,以后会在博客上总结⼀些⼯作上的细节,和技术学习上的总结。希望多多⽀持,多多交流。⼀起进步。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论