Mybatis uses foreach batch insertion to solve the problem that the sequence is only queried once (here, I only look at the union all part)

The oracle bulk insert method is:
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

because the project uses sequence Generate id, the initial wording:
<!-- batch insert, 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}
The query method of                   from dual
             </foreach>
     </insert>
is only one query, which causes the id of the objects in the list to be the same when re-inserted, which violates the uniqueness constraint of the primary key.

So modify it to the following form:
<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"

                 #{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>
put the id in the foreach Remove the data spelled out by foreach as a table A, and then query the data from table A, and then connect the value read from the sequence as the id. In this way, the value of the sequence will be read multiple times, and the id will be different.
<selectKey resultType="long" keyProperty="id" order="BEFORE">
            SELECT SEQ_xxx_DETAIL.
        </selectKey> It will report an error after deleting: SQL command not properly ended. The reason has not been found for the time being. If you know the reason, please tell me.
Use this article to start a discussion, hoping to have a more appropriate way.

The batch insert of mysql is as follows:
INSERT INTO MyTable(ID,NAME) VALUES(7,'003'),(8,'004'),(9,'005')
And mysql has auto-increment fields, you can set id to Self-increasing, in this case, there is no consistent 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> 

Guess you like

Origin blog.csdn.net/keepfriend/article/details/113849646