逐条更新

  这种方式显然是最简单,也最不容易出错的,即便出错也只是影响到当条出错的数据,而且可以对每条数据都比较可控。

代码

 updateBatch(List<MyData> datas){
for(MyData data : datas){
try{
myDataDao.update(data);
}
catch(Exception e){
}
}
}

mybatis中update的实现

 <update>
update mydata
set ...
where ...
</update>

单字段批量更新

  逐条更新最然简单,但是逐次连接断开数据库效率实在不高,因此诞生了批量更新的方法。

 <update id="updateBatch" parameterType="java.util.List">
update mydata_table
set status=
<foreach collection="list" item="item" index="index" separator=" " open="case ID" close="end">
when #{item.id} then #{item.status}
</foreach>
where id in
<foreach collection="list" index="index" item="item" separator="," open="(" close=")">
#{item.id,jdbcType=BIGINT}
</foreach>
</update>

  其中when...then...是sql中的"switch" 语法。这里借助mybatis的<foreach>语法来拼凑成了批量更新的sql,上面的意思就是批量更新id在updateBatch参数所传递List中的数据的status字段。也可以使用<trim>实现同样的功能。

 <update id="updateBatch" parameterType="java.util.List">
update mydata_table
<trim prefix="set" suffixOverrides=",">
<trim prefix="status =case" suffix="end,">
<foreach collection="list" item="item" index="index">
when id=#{item.id} then #{item.status}
</foreach>
</trim>
</trim>
where id in
<foreach collection="list" index="index" item="item" separator="," open="(" close=")">
#{item.id,jdbcType=BIGINT}
</foreach>
</update>

  prefix,suffix 表示在trim标签包裹的部分的前面或者后面添加内容,如果同时有prefixOverrides,suffixOverrides 表示会用prefix,suffix覆盖Overrides中的内容。

如果只有prefixOverrides,suffixOverrides 表示删除开头的或结尾的xxxOverides指定的内容。

 上述代码转化成sql如下:

 update mydata_table
set status =
case
when id = #{item.id} then #{item.status}
...
end
where id in (...);

带条件多字段批量更新

 <update id="updateBatch" parameterType="java.util.List">
update sys_user
<trim prefix="set" suffixOverrides=",">
<trim prefix="userName = case" suffix="end,">
<foreach collection="list" item="item" index="index">
<if test="item.userName != null">
when userId=#{item.userId} then #{item.userName}
</if>
</foreach>
</trim>
<trim prefix="userCode = case" suffix="end,">
<foreach collection="list" item="item" index="index">
<if test="item.userCode != null or item.userName == null">
when userId=#{item.userId} then #{item.userCode}
</if>
</foreach>
</trim>
</trim>
where userId in
<foreach collection="list" index="index" item="item" separator="," open="(" close=")">
#{item.userId}
</foreach>
</update>

  这种批量跟心数据库的方式可以在一次数据库连接中更新所有数据,避免了频繁数据库建立和断开连接的开销,可以很大程度的提高数据更新效率。但是这样的问题是如果这个过程中更新出错,将很难知道具体是哪个数据出错,如果使用数据自身的事务保证,那么一旦出错,所有的更新将自动回滚。而且通常这种方式也更容易出错。因此通常的使用的方案是进行折中,也就是一次批量更新一部分(分页进行更新,比如说一共有1000条数据,一次更新100条)。这样可以分担出错的概率,也更容易定位到出错的位置。 当然如果数据量确实很大的时候,这种批量更新也一样会导致更新效率低下(比如说一次更新100条,那如果10亿条数据呢,一样要批量更新1000万次,建立和断开1000万次数据库,这个效率是无法承受的)。这时候也许只能考虑其他方案了,比如引入缓存机制等。

MyBatis批量更新的更多相关文章

  1. mybatis批量更新报错badsql

    mybatis批量更新时语法写的都对,但是报错,需要在连接上面加上allowMultiQueries=true 示例:jdbc:MySQL://192.168.1.236:3306/test?useU ...

  2. mybatis批量更新update-设置多个字段值 报错 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near

    mybatis批量更新update-设置多个字段值 2016年08月01日 12:49:26 姚一号 阅读数:29539 标签: mysql mybatis批量更新批量更新allowMultiQuer ...

  3. Mybatis批量更新<转>

    Mybatis批量更新 批量操作就不进行赘述了.减少服务器与数据库之间的交互.网上有很多关于批量插入还有批量删除的帖子.但是批量更新却没有详细的解决方案. 实现目标 这里主要讲的是1张table中.根 ...

  4. Mybatis批量更新详解

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

  5. mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样

    Mybatis批量更新数据 mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样 mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样 mybatis批 ...

  6. mybatis批量更新策略

    我们知道循环中操作db会导致连接数满,严重影响数据库性能.所以在对db进行DQL与DML时,根据业务逻辑尽量批量操作,这里我们介绍下使用mybatis批量更新mysql的两种方式. 方式一: < ...

  7. Mybatis批量更新数据库与批量插入数据库(以oracle为例)

    一.批量更新 1.普通写法(一条记录update一次,性能比较差,容易造成阻塞.不建议使用) <update id="updateBatch" parameterType=& ...

  8. mybatis 批量更新 Parameter '__frch_item_0' not found. Available parameters are [list]

    一次在做批量更新数据的时候报错 Parameter '__frch_item_0' not found. Available parameters are [list] 记过反复查找,最后才发现是一个 ...

  9. mybatis批量更新报错 org.mybatis.spring.MyBatisSystemException

    具体报错信息: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.Bin ...

随机推荐

  1. [Java in NetBeans] Lesson 13. Multidimensional Arrays

    这个课程的参考视频和图片来自youtube. 主要学到的知识点有: 1. Multidimensional Array: Array that has more than one dimension. ...

  2. nodejs+mysql入门实例(链接到数据库)

    //连接数据库 var mysql = require('mysql'); var connection = mysql.createConnection({ host: '******', //数据 ...

  3. Github Pages 搭建网站

    参考网站: https://pages.github.com/ http://gitbeijing.com/pages.html 搬进github:http://gitbeijing.com

  4. linux 编译 'aclocal-1.14' is missing on your system

    centos编译出现:类似情况: $tar -xvf libpcap-1.0.0.tar.gz      $cd libpcap-1.0.0.tar.gz      $./configure      ...

  5. Node.JS 项目打包 JXCore

    哈哈,又回来了 当你开发完成了Node.JS项目,你应该需要打包发行吧 好,JXCore就是干这个的啦! 嗯,可能你会这样来安装 1. curl http://jxcore.com/xil.sh | ...

  6. 如何快速知道一个颜色的rgb值

    1.如果你想使用某种颜色缺不知道rgb值是多少,可以将一张图片用系统自带的画图(我的系统是win7)0工具打开,点击编辑颜色就会出现调色板,然后就可以选择查看具体颜色的rgb值了 2.如果你想知道某个 ...

  7. ida6.8 android so调试

    献给还不会的同学. 我的设备 1.魅族手机,自带root功能 2.ida6.8 1.上传ida 目录下dbgsrv/android_server 到 手机上,这个目录自己可以修改,网上都用的adb p ...

  8. ubuntu16.4菜单栏不见,终端不见解决方法

    1.ctrl+alt+f1进入命令行 2. sudo apt-get install gnome-terminal 3.sudo apt-get install unity 4.setsid unit ...

  9. 35.HTML--网页自动跳转 5种方法

    网页自动跳转 5种方法 利用HTML标记(META中的REFRESH属性) 用HTML标记,就是用META的REFRESH标记,举例如下: <meta http-equiv=refresh co ...

  10. 让bat以管理员权限运行

    有的电脑是非管理员登录,运行程序时,需要提示是否运行运行.解决方法如下: @ echo off % % ver|find "5.">nul&&goto :Ad ...