探讨批量更新数据三种写法的效率问题。

实现方式有三种,

1> 用for循环通过循环传过来的参数集合,循环出N条sql,需要在db链接url后面带一个参数  &allowMultiQueries=true 

2> 用mysql的case when 条件判断变相的进行批量更新(推荐使用) 

3> 用ON DUPLICATE KEY UPDATE进行批量更新

 <!-- 批量更新第一种方法,通过接收传进来的参数list进行循环着组装sql ;号分割 --><update id="updateBatch" parameterType="java.util.List" ><foreach collection="list" item="item" index="index" open="" close="" separator=";">update standard_relation<set ><if test="item.standardFromUuid != null" >standard_from_uuid = #{item.standardFromUuid,jdbcType=VARCHAR},</if><if test="item.standardToUuid != null" >standard_to_uuid = #{item.standardToUuid,jdbcType=VARCHAR},</if><if test="item.gmtModified != null" >gmt_modified = #{item.gmtModified,jdbcType=TIMESTAMP},</if></set>where id = #{item.id,jdbcType=BIGINT}</foreach></update><!-- 批量更新第二种方法,通过 case when语句变相的进行批量更新 -->prefix:在trim标签内sql语句加上前缀。suffix:在trim标签内sql语句加上后缀。prefixOverrides:指定去除多余的前缀内容suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。<update id="updateBatch" parameterType="java.util.List" >update standard_relation<trim prefix="set" suffixOverrides=","><trim prefix="standard_from_uuid =case" suffix="end,"><foreach collection="list" item="i" index="index"><if test="i.standardFromUuid!=null">when id=#{i.id} then #{i.standardFromUuid}</if></foreach></trim><trim prefix="standard_to_uuid =case" suffix="end,"><foreach collection="list" item="i" index="index"><if test="i.standardToUuid!=null">when id=#{i.id} then #{i.standardToUuid}</if></foreach></trim><trim prefix="gmt_modified =case" suffix="end,"><foreach collection="list" item="i" index="index"><if test="i.gmtModified!=null">when id=#{i.id} then #{i.gmtModified}</if></foreach></trim></trim>where<foreach collection="list" separator="or" item="i" index="index" >id=#{i.id}</foreach></update><!-- 批量更新第三种方法,用ON DUPLICATE KEY UPDATE  --><insert id="updateBatch" parameterType="java.util.List">insert into standard_relation(id,relation_type, standard_from_uuid,standard_to_uuid, relation_score, stat,last_process_id, is_deleted, gmt_created,gmt_modified,relation_desc)VALUES<foreach collection="list" item="item" index="index" separator=",">(#{item.id,jdbcType=BIGINT},#{item.relationType,jdbcType=VARCHAR}, #{item.standardFromUuid,jdbcType=VARCHAR},#{item.standardToUuid,jdbcType=VARCHAR}, #{item.relationScore,jdbcType=DECIMAL}, #{item.stat,jdbcType=TINYINT},#{item.lastProcessId,jdbcType=BIGINT}, #{item.isDeleted,jdbcType=TINYINT}, #{item.gmtCreated,jdbcType=TIMESTAMP},#{item.gmtModified,jdbcType=TIMESTAMP},#{item.relationDesc,jdbcType=VARCHAR})</foreach>ON DUPLICATE KEY UPDATEid=VALUES(id),relation_type = VALUES(relation_type),standard_from_uuid = VALUES(standard_from_uuid),standard_to_uuid = VALUES(standard_to_uuid),relation_score = VALUES(relation_score),stat = VALUES(stat),last_process_id = VALUES(last_process_id),is_deleted = VALUES(is_deleted),gmt_created = VALUES(gmt_created),gmt_modified = VALUES(gmt_modified),relation_desc = VALUES(relation_desc)</insert>

方案二中的实际瓶装后的sql:

 update standard_relationset standard_from_uuid =case when id=#{i.id} then #{i.standardFromUuid} when id=#{i.id} then #{i.standardFromUuid} end,standard_to_uuid =case  when id=#{i.id} then #{i.standardToUuid} when id=#{i.id} then #{i.standardToUuid} end,gmt_modified =case when id=#{i.id} then #{i.gmtModified} when id=#{i.id} then #{i.gmtModified} endwhere id=#{i.id} or id=#{i.id}CASE WHEN的两种写法:Type 1: CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] ENDType 2: CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END

对应的Java代码:


@Overridepublic void updateStandardRelations() {List<StandardRelation> list=standardRelationMapper.selectByStandardUuid("xiemingjieupdate");for(StandardRelation tmp:list){tmp.setStandardFromUuid(tmp.getStandardFromUuid()+"update");tmp.setStandardToUuid(tmp.getStandardToUuid()+"update");}long begin=System.currentTimeMillis();standardRelationManager.updateBatch(list);long end=System.currentTimeMillis();System.out.print("当前的批量更新的方法用时"+(end-begin)+"ms");}

扩展:  多个条件批量更新 ( 注意:  update的字段不要包含 条件字段 !!! , field2也需要set, 那么mysql回先执行setfield2字段,导致其他字段条件不匹配!!!  )


<update id="updateBatch" parameterType="java.util.List">update demo_table<trim prefix="set" suffixOverrides=",">status=<foreach collection="list" item="item" open="case " close=" end,">when field2=#{item.field2} and company_id=#{item.field3} then #{item.status}</foreach>create_time =<foreach collection="list" item="item" open="case " close=" end,">when field2=#{item.field2} and company_id=#{item.field3} then<choose><when test="item.createTime!=null">#{item.createTime}</when><otherwise>now()</otherwise></choose></foreach></trim>WHERE<foreach collection="list" item="item" open="( " separator=") or (" close=" )">device_num=#{item.field2} and company_id=#{item.field3}</foreach></update>

对应的sql

  update demo_table set status = case      when field2=#{item.field2} and company_id=#{item.field3} then #{item.status} when field2=#{item.field2} and company_id=#{item.field3} then #{item.status} end,create_time= case  when field2=#{item.field2} and company_id=#{item.field3} then #{item.createTime}          when field2=#{item.field2} and company_id=#{item.field3} then #{item.createTime} end,WHERE (device_num=#{item.field2} and company_id=#{item.field3})or (device_num=#{item.field2} and company_id=#{item.field3})

效率比较:

sql语句for循环效率其实相当高的,因为它仅仅有一个循环体,只不过最后update语句比较多,量大了就有可能造成sql阻塞

case when虽然最后只会有一条更新语句,但是xml中的循环体有点多,每一个case when 都要循环一遍list集合,所以大批量拼sql的时候会比较慢,所以效率问题严重。使用的时候建议分批插入。

duplicate key update可以看出来是最快的,但是一般大公司都禁用,公司一般都禁止使用replace into和INSERT INTO … ON DUPLICATE KEY UPDATE,这种sql有可能会造成数据丢失和主从上表的自增id值不一致。而且用这个更新时,记得一定要加上id,而且values()括号里面放的是数据库字段,不是java对象的属性字段。

根据效率,安全方面综合考虑,选择适合的很重要。

参考原文:mybatis批量更新数据三种方法效率对比_oneStep->next=CloserNow-CSDN博客_mybatis 批量更新

//两表关联更新
UPDATE video_audit_picture t1 JOIN video_audit t2
ON t1.video_id = t2.id
SET t1.video_code = t2.video_code;

mybatis批量更新数据三种方法效率对比相关推荐

  1. mybatis批量更新数据三种方法

    具体的可以参考下面链接: ​​​​​​mybatis批量更新数据三种方法效率对比_PreciousLife的博客-CSDN博客_mybatis 批量更新 此处说明下,若是使用for循环遍历方式,来生成 ...

  2. Mybatis批量更新数据

    Mybatis批量更新数据 第一种方式 [html] view plaincopy print? <update id="updateBatch" parameterType ...

  3. DataTable数据批量写入数据库三种方法比较

    DataTable数据批量写入数据库三种方法比较 标签: it 分类: C# 1)   insert循环插入: 2)   sqldataadapter.update(dataset,tablename ...

  4. dapper mysql 批量_MySQL数据库之c#mysql批量更新的两种方法

    本文主要向大家介绍了MySQL数据库之c#mysql批量更新的两种方法 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 总体而言update 更新上传速度还是慢. 1:  简单的 ...

  5. node.js中mysql批量插入更新的三种方法

    [背景]在项目中遇到一个批量插入数据的需求,由于之前写过的sql语句都是插入一个对象一条数据,于是去网上搜关键词 "sql批量插入"."mysql批量插入"等, ...

  6. java mybatis 批量更新数据_Mybatis批量更新详解

    转:http://www.cnblogs.com/winkey4986/p/3915151.html Mybatis批量更新 批量操作就不进行赘述了.减少服务器与数据库之间的交互.网上有很多关于批量插 ...

  7. mysql update 批量更新_mysql 批量更新的两种方法

    本文介绍两种批量更新数据方法 数据准备 create table account ( id int auto_increment primary key, balance int not null ) ...

  8. oracle如何根据ID恢复部分数据,三种方法找回Oracle数据库误删除的数据

    三种方法找回Oracle数据库误删除的数据 最新动态来源:点击数:6141更新时间:2018/5/10 有很多朋友都遇到过在操作数据库时误删除某些重要数据的情况,如果数据库没有备份而且数据有十分重要的 ...

  9. sublime 设置自动更新_Win10关闭自动更新的三种方法

    Win10怎么关闭自动更新呢?很多人都不知道,下面小编来告诉大家. 第一种方法 我们右击电脑左下角的微软按钮,弹出的界面,我们点击运行: 弹出的运行中,我们输入services.msc,之后点击确定: ...

最新文章

  1. WordPress导出全静态化网站
  2. Execute permission missing on User-Defined table Type
  3. ImageView和onTouchListener实现,点击查看图片细节
  4. 基于阈值的损失函数_【代码+推导】常见损失函数和评价指标总结
  5. Boost:使用max_element()算法以及transform_iterator和length()函数来查找最长的 向量数组中的4分量向量
  6. java 访问线程_java线程简介(共享对数据的访问)
  7. 提高django model效率的几个小方法
  8. 市面上有哪几种门_实木门、原木门、模压门,各有门道不怕坑!
  9. java 多态 转型
  10. 如何查看google chrome 插件源码
  11. 完美解决SpringMVC中静态资源无法找到(No mapping found for HTTP request with URI)问题...
  12. 北大等多所高校网站被挂马 高考生浏览需小心
  13. 计算机应用技术三级学科,三个计算机专业的区别是什么?
  14. 考虑购买的 DELL 配置
  15. 不需要写代码,快速批量修改文件夹中图片的格式
  16. 电商(一) 创建订单业务流程
  17. Java最佳学习途径
  18. pid倒立摆matlab,基于MATLAB的直线一级倒立摆的PID控制研究
  19. 数据结构与算法——慕课作业——第一章 概论 + 第二章 线性表
  20. [转载]波斯亡国君为何选择大唐避难?

热门文章

  1. 网络显示连接,不能还是上网,找不到DNS怎么办?
  2. uni-app 微信小程序端-AirKiss一键配网
  3. android烤机按键变慢,Android8.0平台Camera monkey拷机卡死异常
  4. 自然语言处理之hmm(隐马尔可夫模型)
  5. 希腊字母常用指代意义及其中英文读音
  6. 罗永浩改造苹果iPad,装了个门把手
  7. 奋斗吧之“和loser对话”小故事
  8. 「奋斗者协议」又来了:自愿加班、接受淘汰、不与公司发生法律纠纷
  9. Notion数字笔记使用教程
  10. elang和python互通的例子