mybatis使用foreach批次插入多个,解决<selectKey>只作用一次的问题

1,oracle插入单条语句应用selectKey标签方式:

  <insert id="insertCustomerInfo" >
        <selectKey resultType="String" order="BEFORE" keyProperty="customerId">
            select SEQ_XMGL_CUSTOMER_ID.nextval from sys.dual
        selectKey>
    Insert INTO DM_XMGL_CUSTOMER_INFO
		 ( 	CUSTOMER_ID,
            CUSTOMER_NAME,
            AREA_CODE,
            AREA_NAME,
            DETAILS_ADDRESS,
            Postal_Code,
            PHONE_NUMBER,
            CUSTOMER_TYPE_CODE,
            CUSTOMER_TYPE_NAME,
            REMARKS,
            IS_DELETE
            ) VALUES
            (#{customerId},#{customerName},#{areaCode},#{areaName},#{detailsAddress},#{postalCode},
            #{phoneNumber},#{customerTypeCode},#{customerTypeName},#{remarks},1)
    insert>

注意:
selectKey 标签中的keyProperty="customerId"要和#{customerId}下面赋值命名一致,代表#{customerId}引用的是selectKey 标签查询的值、
order="BEFORE"代表先执行selectKey,再执行插入语句,相反还有after。

2,oracle批次插入多个

无主键:

 <insert id="insertContactsInfo" >
            Insert ALL
                <foreach collection="contactsDTOList" item="dto" index="index">
            INTO  DM_XMGL_CONTACTS_INFO
            (
            CONTACTS_NAME,
            CONTACTS_PHONE,
            CREATE_TIME,
            CREATE_USER_CODE,
            CREATE_USER_NAME,
            IS_DELETE,
            IS_VALID
            )VALUES(
            #{dto.contactsName},#{dto.contactsPhone},SYSDATE,#{createUserCode},
            #{createUserName},1,1)
        foreach>
        SELECT 1 FROM DUAL

SELECT 1 FROM DUAL 是要加的
有主键:
错误:

 <insert id="insertContactsInfo" >
  <selectKey resultType="String" order="BEFORE" keyProperty="customerId">
            select SEQ_XMGL_CUSTOMER_ID.nextval from sys.dual
        selectKey>
            Insert ALL
                <foreach collection="contactsDTOList" item="dto" index="index">
            INTO  DM_XMGL_CONTACTS_INFO
            (CUSTOMER_ID,
            CUSTOMER_NAME,
            CONTACTS_NAME,
            CONTACTS_PHONE,
            CREATE_TIME,
            CREATE_USER_CODE,
            CREATE_USER_NAME,
            IS_DELETE,
            IS_VALID
            )VALUES(
            #{customerId}, #{customerName},#{dto.contactsName},#{dto.contactsPhone},SYSDATE,#{createUserCode},
            #{createUserName},1,1)
        foreach>
        SELECT 1 FROM DUAL
    insert>

这样会导致插入的多条信息的主键customerId是一样的,不合适。
然而selectKey标签不能放在foreach循环里面,这时就要手动查询主键
首先看下对应oracle对应基本语句形式:

insert  into TABLENAME(id, name)
        select c_id, c_name from tablename1 where id=?
        union all select c_id, c_name from tablename2 where id=?
        

这样会吧子查询的两个select拼接为一张表再插入到TABLENAME中,所以:
正确:

 <insert id="insertMilepost">
    Insert INTO DM_XMGL_MILEPOST_INFO
        (MILEPOST_CODE,
        CONTRACT_CODE,
        CONTRACT_NAME,
        MILEPOST_STAGE,
        MILEPOST_NAME,
        MILEPOST_MONEY,
        START_DATE,
        END_DATE,
        REMARKS,
        IS_DELETE,
        IS_VALID)
        SELECT SEQ_XMGL_MILEPOST_ID.nextval ,A.* from(
        <foreach collection="milepostDTOs" item="dto" index="index" separator="union all">
        select
            T.CONTRACT_CODE,
            T.CONTRACT_NAME,
            #{dto.milepostStage} MILEPOST_STAGE , /*里程碑阶段*/
            #{dto.milepostName} MILEPOST_NAME , /*里程碑名称*/
            #{dto.milepostMoney} MILEPOST_MONEY, /*里程碑金额*/
            to_date(#{dto.startDate},'YYYY-MM-DD HH24:MI:SS') START_DATE, /*开始时间*/
            to_date(#{dto.endDate},'YYYY-MM-DD HH24:MI:SS') END_DATE, /*结束时间*/
            #{dto.remarks} REMARKS, /*备注*/
            '1' IS_DELETE,
            '1' IS_VALID
            FROM V_DM_XMGL_CONTRACT
            T,sys.dual
            WHERE T.CONTRACT_CODE = #{dto.contractCode} /*合同编码参数*/
        foreach>
        ) A
    insert>

这样手动查询主键ID和selectKey标签中的语句作用是一样的(其实每次手动执行一遍select SEQ_XMGL_MILEPOST_ID.nextval from sys.dual都会自动累加的),解决了批量插入并且插入不同主键的问题。

你可能感兴趣的:(spring,boot,sql,数据库,oracle,java)