Mybatis批量插入和批量更新数据的资料相信大家从网上能查找到很多资料,本文重点总结一下mybatis执行批量插入insert和批量更新update数据。在mysql数据库中批量插入,如:insert into ... values (),(),...语法;而在oracle数据库中批量插入如:insert into selcect ... union all select ...语法。
mysql批量插入
INSERT INTO T_P_ROLE_MODULE (ROLE_ID, MODULE_ID)
VALUES
separator=",">
( #{item.roleId}, #{item.moduleId})
oracle批量插入
INSERT INTO T_P_ROLE_MODULE (ROLE_ID, MODULE_ID)
SELECT #{item.roleId}, #{item.moduleId} FROM DUAL
如果传入多个参数时需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果在传入参数的时候,在breast里面也是会把它封装成一个Map的,map的key就是参数名,所以collection属性值就是传入的List或array对象封装的map里面的key值。
测试这种方式可行性并插入指定序列,参考配置如下:
SELECT SEQ_XXX.NEXTVAL , #{item.roleId}, #{item.moduleId} FROM DUAL
报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-02287The 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的配置可以修改成如下:
open="select SEQ_XXX.NEXTVAL, a.* from (" close=") a">
select #{item.code,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR} from dual
参考资料: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&characterEncoding=UTF-8&allowMultiQueries=true
update test test=${item.test}+1 where id = ${item.id}
oracle批量更新
update test test=${item.test}+1 where id = ${item.id}
Mybatis中sql配置文件属性参数含义说明,参考图:
对于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