博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mybatis使用foreach批次插入,解决sequence只查询一次的问题(在此,我只看union all 部分)
阅读量:4293 次
发布时间:2019-05-27

本文共 3590 字,大约阅读时间需要 11 分钟。

oracle的批量插入方式是:
insert  into db(id, zgbh, shbzh)
        select '1', '2', '3' from dual
        union all select '2', '3', '4' from dual
        union all select '3', '4', '5' from dual
        union all select '4', '5', '6' from dual
        union all select '5', '6', '7' from dual
由于项目使用到sequence生成id,刚开始的写法:
<!-- 批次插入,List-->
     <insert id="insertList" useGeneratedKeys="true" parameterType="java.util.List">
        <selectKey resultType="long"
keyProperty="id" order="BEFORE">
            SELECT SEQ_xxx_DETAIL.NEXTVAL FROM DUAL
        </selectKey>
         insert into TBL_xxx_DETAIL
              (
                 <include refid="allColumns"/>
              )
              <foreach collection="list" item="item" index="index"  separator="UNION ALL" >
                  SELECT
                
#{id, jdbcType=NUMERIC javaType=long},
                 #{item.batchFundTitleId, jdbcType=NUMERIC javaType=long},
                 #{item.transactionRequestId, jdbcType=NUMERIC javaType=long},
                 #{item.arAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
                 #{item.bankServiceAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
                 #{item.receivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
                 #{item.realReceivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
                 #{item.verifyDate, jdbcType=DATE javaType=date},
                 #{item.verifyOp, jdbcType=VARCHAR javaType=string},
                 #{item.verifyStatus, jdbcType=INTEGER javaType=int},
                 #{item.created, jdbcType=VARCHAR javaType=string},
                 #{item.createdDate, jdbcType=DATE javaType=date},
                 #{item.createdIp, jdbcType=VARCHAR javaType=string},
                 #{item.modified, jdbcType=VARCHAR javaType=string},
                 #{item.modifiedDate, jdbcType=DATE javaType=date},
                 #{item.modifiedIp, jdbcType=VARCHAR javaType=string}
                  from dual
             </foreach>
     </insert>
这样的写法sequence的查询方法只查询一次,造成list中的对象的再插入时id都会一样,违反主键的唯一性约束。
所以修改为如下的形式:
<insert id="insertList" useGeneratedKeys="true" parameterType="java.util.List">
       
<selectKey resultType="long" keyProperty="id" order="BEFORE">
            SELECT SEQ_xxx_DETAIL.NEXTVAL FROM DUAL
        </selectKey>
         insert into TBL_xxx_DETAIL
              (
                 <include refid="allColumns"/>
              )
select  SEQ_xxx_DETAIL.NEXTVAL,A.*  from(
              <foreach collection="list" item="item" index="index"  separator="UNION ALL" >
                  SELECT
                 #{item.batchFundTitleId, jdbcType=NUMERIC javaType=long},
                 #{item.transactionRequestId, jdbcType=NUMERIC javaType=long},
                 #{item.arAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
                 #{item.bankServiceAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
                 #{item.receivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
                 #{item.realReceivedAmt, jdbcType=DECIMAL javaType=java.math.BigDecimal},
                 #{item.verifyDate, jdbcType=DATE javaType=date},
                 #{item.verifyOp, jdbcType=VARCHAR javaType=string},
                 #{item.verifyStatus, jdbcType=INTEGER javaType=int},
                 #{item.created, jdbcType=VARCHAR javaType=string},
                 #{item.createdDate, jdbcType=DATE javaType=date},
                 #{item.createdIp, jdbcType=VARCHAR javaType=string},
                 #{item.modified, jdbcType=VARCHAR javaType=string},
                 #{item.modifiedDate, jdbcType=DATE javaType=date},
                 #{item.modifiedIp, jdbcType=VARCHAR javaType=string}
                  from dual
             </foreach>
) A
     </insert>
把foreach中的id去掉,foreach拼出来的数据作为一张表A,然后从表A中查询数据,再接上从sequence中读取的值作为id。这样sequence的值就会多次读取,id就会不一样。
<selectKey resultType="long" keyProperty="id" order="BEFORE">
            SELECT SEQ_xxx_DETAIL.NEXTVAL FROM DUAL
        </selectKey>
删除后会报错:SQL command not properly ended,暂时没有查出来原因,有知道的原因的请告诉我哈。
以此文抛砖引玉吧,希望能有更合适的方式。
mysql的批量插入如下:
INSERT INTO MyTable(ID,NAME) VALUES(7,'003'),(8,'004'),(9,'005')
而且mysql有自增字段,可以把id设置为自增的,这样的话就不存在id一致的情况。
<insert id="insertBatch" > 
    insert into student ( NAME,SEX,ADDRESS,TELEPHONE,TID)  
    values  
    <foreach collection="list" item="item" index="index" open="(" separator=","  close=")"> 
         #{item.name},
         #{item.sex},
         #{item.address},
         #{item.telephone},
         #{item.tId} 
    </foreach> 
</insert> 

转载地址:http://afzws.baihongyu.com/

你可能感兴趣的文章
PowerDesigner(数据建模)使用大全
查看>>
RadioButton与CheckBox_优就业
查看>>
java中的throw与throws的区别
查看>>
优化用户登录体验效果
查看>>
用js批量选中功能实现更改数据库中status状态值_优就业
查看>>
MySql表信息基础知识学习
查看>>
为什么document找到的不是html节点_优就业
查看>>
Javascript本地存储小结
查看>>
常用排序方法介绍
查看>>
Java异常分类和统一处理
查看>>
原 荐 cache线程池对数据库操作的饥饿问题
查看>>
使用Eclipse把java文件打包成jar 含有第三方jar库的jar包
查看>>
3种web会话管理的方式
查看>>
SSM(框架)-异常1:面向接口式编程异常
查看>>
Android蓝牙4.0之玩爆智能穿戴、家具(二)
查看>>
使用Condition实现多线程之间调用
查看>>
javaAPI之String
查看>>
JQ 新窗口打开链接并设置参数
查看>>
JS中常遇到的浏览器兼容问题和解决方法
查看>>
JAVA学习笔记之-servlet知识点
查看>>