oracle 和 mysql 实现批量插入时由一点的差别,一定要注意这一点,否者就会报错,报各种错误。下面我就来展示一下oracle + mybatis 实现批量插入的方法并且会指明一些需要注意的点。
由于oracle没有主键自增的功能,这里使用了序列实现主键的自增。在批量插入时,如果没有正确使用序列,咋会报禁止使用序列这个异常。具体看下面的代码怎么实现批量插入的。
xml中sql的部分。
注意图片上话圈的地方
- useGeneratedKeys="false"设置为false,因为oracle 中没有主键自增。
- collection="list"中的值分为三种情况
(1)如果传入的是单参数且参数类型是一个List的时候,collection属性值为list .
(2)如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array .
(3)如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key. - MTS_ETL_LOG_SEQ.nextval 这个是序列的使用,位置一定要对,(当时笔者就是在这里坑着了)
- separator=“UNION” 这里和mysql不一样,不能使用逗号区分,这里也是很坑的。如果不使用的话会报值过多的错误
下面就是具体的代码展示
<!--批量插入-->
<insert id="insertBatchMtsEtl" useGeneratedKeys="false">
insert into MTS_ETL_LOG select MTS_ETL_LOG_SEQ.nextval,A.* from (
<foreach collection="list" item="log" index="index"
separator="UNION"
>
select
to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') , #{log.wfDcdataDate,jdbcType=VARCHAR},
#{log.wfDcdataId,jdbcType=VARCHAR}, #{log.wfDcdataEnname,jdbcType=VARCHAR},
#{log.wfDcdataCnname,jdbcType=VARCHAR},
#{log.wfDcdataBgtime,jdbcType=VARCHAR}, #{log.wfDcdataEdtime,jdbcType=VARCHAR},
#{log.wfDcdataResult,jdbcType=VARCHAR},
#{log.nodeId,jdbcType=VARCHAR}, #{log.nodeEnname,jdbcType=VARCHAR}, #{log.nodeCnname,jdbcType=VARCHAR},
#{log.nodeBgtime,jdbcType=VARCHAR}, #{log.nodeEdtime,jdbcType=VARCHAR}, #{log.nodeResult,jdbcType=VARCHAR},
#{log.nodeStatus,jdbcType=VARCHAR}, #{log.nodeErrorinfo,jdbcType=VARCHAR},
#{log.successRows,jdbcType=DECIMAL},
#{log.failRows,jdbcType=DECIMAL}, #{log.refuseRows,jdbcType=DECIMAL}, #{log.allRows,jdbcType=DECIMAL}
from dual
</foreach>)A
这里有彩蛋:
序列的实现
create sequence seq_userid //系列名
increment by 1 //每次增加几
start with 1 //从几开始
maxvalue 99999 最大值
cycle
nocache;
序列在mybatis中使用