原创

mybatis执行批量插入insert和批量更新update

Mybatis批量插入和批量更新数据的资料相信大家从网上能查找到很多资料,本文重点总结一下mybatis执行批量插入insert和批量更新update数据。在mysql数据库中批量插入,如:insert into ... values (),(),...语法;而在oracle数据库中批量插入如:insert into selcect ... union all select ...语法

mysql批量插入

<insert id="addRoleModule" parameterType="java.util.List">
    INSERT INTO T_P_ROLE_MODULE (ROLE_ID, MODULE_ID)
    VALUES <foreach collection="list" item="item" index="index"  
    separator=",">  
    ( #{item.roleId}, #{item.moduleId})  
    </foreach>  
</insert>

oracle批量插入

<insert id="addRoleModule" parameterType="java.util.List">
    INSERT INTO T_P_ROLE_MODULE (ROLE_ID, MODULE_ID)
    <foreach collection="list" item="item" index="index" separator=" UNION ALL ">  
    SELECT #{item.roleId}, #{item.moduleId} FROM DUAL
    </foreach>  
</insert>

如果传入多个参数时需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果在传入参数的时候,在breast里面也是会把它封装成一个Map的,map的key就是参数名,所以collection属性值就是传入的List或array对象封装的map里面的key值。

测试这种方式可行性并插入指定序列,参考配置如下:

    <foreach collection="list" item="item" index="index" separator=" UNION ALL ">  
  SELECT SEQ_XXX.NEXTVAL , #{item.roleId}, #{item.moduleId} FROM DUAL
    </foreach>

ORA-02287: sequence number not allowed here错误异常。ORA-02287错误网上最多的例子就是序列不能跟group by一起使用,解决方法就是把group by语句包起来,外层再select序列就可以了。目前这个错误显示不是group by的问题,也有神似大仙的人物建议使用oracle的insert all,可这个是将数据插入多张表的语句,与当前问题不属于同一范畴。在一个wiki里看到ORA-02287错误的详细描述:http://www.orafaq.com/wiki/ORA-02287

The following are the cases where you can't use a sequence:
For a SELECT Statement:
In a WHERE clause
In a GROUP BY or ORDER BY clause
In a DISTINCT clause
Along with a UNION or INTERSECT or MINUS
In a sub-query
Other areas:
A sub-query of Update or Delete
In a View or snapshot
In a DEFAULT or CHECK Condition of a table definition
Within a single SQL statement that uses CURRVAL or NEXTVAL, all referenced LONG columns, updated tables, 
and locked tables must be located on the same database.

其中讲到union中也不用使用序列。UNION 指令的目的是将两个 SQL 语句的结果合并起来,可以查看你要的查询结果. UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。 UNION ALL的用法和union一样,只不过union含有distinct的功能,它会把两张表了重复的记录去掉,而union all不会,所以从效率上,union all 会高一点。

这里就是union中不能使用序列的问题,将select序列语句再往里包一层也是不行的,union会嵌套向里层检查。往里包不行,就往外包,写成这样可行

select SEQ_XXX.NEXTVAL, a.* from
(select 1,'66' from dual union
select 2,'77' from dual) a

于是foreach的配置可以修改成如下:

    <foreach collection="list" item="item" index="index" separator="union all" 
    open="select SEQ_XXX.NEXTVAL, a.* from (" close=") a">
      select #{item.code,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR} from dual
    </foreach>

参考资料:http://ljhzzyx.blog.163.com/blog/static/38380312201353536375,在mybatis配置中oracle和mysql数据库批量更新update也是有很大的不同之处

mysql批量更新

mysql数据库采用一下写法即可执行,但是数据库连接必须配置:&allowMultiQueries=true,如:jdbc:mysql://blog.yoodb.com:3306/test?useUnicode=true&amp;characterEncoding=UTF-8&allowMultiQueries=true

<update id="batchUpdate" parameterType="java.util.List">
  <foreach collection="list" item="item" index="index" open="" close="" separator=";">
update test <set> test=${item.test}+1 </set> where id = ${item.id}
 </foreach>
</update>

oracle批量更新

<update id="batchUpdate"  parameterType="java.util.List">
   <foreach collection="list" item="item" index="index" open="begin" close="end;" separator=";">
update test <set> test=${item.test}+1 </set> where id = ${item.id}
   </foreach> 
</update>

Mybatis中sql配置文件属性参数含义说明,参考图:

1500620131.png

对于foreach标签的解释参考了网上的资料,具体如下:

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合,foreach元素的属性主要有 item,index,collection,open,separator,close

item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔 符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况:

1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list

2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array

3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map

~阅读全文~人机检测~

关注下方微信公众号“Java精选”(w_z90110),回复关键词领取资料:如Mysql、Hadoop、Dubbo、Spring Boot等,免费领取视频教程、资料文档和项目源码。

Java精选专注程序员推送一些Java开发知识,包括基础知识、各大流行框架(Mybatis、Spring、Spring Boot等)、大数据技术(Storm、Hadoop、MapReduce、Spark等)、数据库(Mysql、Oracle、NoSQL等)、算法与数据结构、面试专题、面试技巧经验、职业规划以及优质开源项目等。其中一部分由小编总结整理,另一部分来源于网络上优质资源,希望对大家的学习和工作有所帮助。

评论

  1. #1

    微风物语 (2019/01/07 09:08:38)回复
    DB2数据库怎么批量更新

  2. #2

    无极天尊 (2017/07/21 17:00:16)回复
    厉害了 ,第一次见 通过xml 进行批量 插入,以前都是 service便利 list集合,一个个插入 ,膜拜大神

    路人甲 (2017/09/21 17:41:48)回复
    谢谢,多多学习,技术每时每刻都在变,只能不停的学习才能进步,加油吧。

分享:

支付宝

微信