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

实现方式有三种,

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. 什么是网络推广带你了解新上线的网站该如何提升关键词排名?
  2. vim C plugins
  3. 简述java异常处理机制
  4. C# .NET MVC 基础提供程序在 Open 上失败
  5. 《影响力》承诺和一致原理深入剖析,人们对自己的选择是很相信的
  6. 国内各大平台的推荐算法,看到360的时候笑喷了……
  7. js正则限制字符串长度_正则笔记(3)万字长文,慎点。
  8. 智能仪器原理及设计C语言,智能仪器仪表课程设计.doc
  9. 理解HBase zookeeper和-Root-/.MET表
  10. 【七】zuul路由网关
  11. ExtJs 入门教程
  12. 如何零成本录制一首单人ACAPPELLA
  13. CS游戏控制台命令大全(来自网络)
  14. 查看svn服务器上的文件,如何在命令行通过SVN命令筛选出修改过的文件并递交
  15. Xshell6复制粘贴快捷设置
  16. 全球光纤接头闭合器(FOSC)收入预计2028年达到42.159亿美元
  17. MIPI DSI协议笔记
  18. 如何删除电脑里的MobileGameMaster文件夹
  19. 【51单片机】OOK无线通讯在无线门磁报警中的应用
  20. 如何正确选择python的版本

热门文章

  1. 关于高精度交流恒流源设计是怎样的?
  2. c语言iota怎么用,常量及iota的简单用法
  3. (2020版) 墙裂推荐这十款精选 IntelliJ Idea 插件
  4. Spring Cloud 异常“ Caused by: java.net.UnknownHostException: discovery.host ”
  5. 【互联网代理方案】——Zookeeper
  6. CAD图形设置:层高与填充设置教程
  7. 语音控制,让家居听你的话
  8. python计算器基础知识_Python基础知识+计算器练习
  9. 换挡周期下,谁将成为厨电品牌的进取者?
  10. 解决win10右键桌面出现闪屏问题