简体   繁体   English

在foreach里面的mybatis 3 selectkey

[英]mybatis 3 selectkey inside foreach

MyBatis 3 - Spring MyBatis 3 - 春天

I want to insert list of items and for every item id has to generate from "TVA_UPSELLADMIN_CHANNEL_SEQ.nextVal" but i am getting .xml validation error that you can't sub-child "selectKey" inside "foreach". 我想插入项目列表,并且每个项目ID必须从“TVA_UPSELLADMIN_CHANNEL_SEQ.nextVal”生成,但我得到.xml验证错误,你不能在“foreach”里面子子“selectKey”。

<insert id="insertServiceMappings" parameterType="java.util.List">

INSERT  
<foreach collection="list" item="channel" index="index" >

<selectKey keyProperty="id" resultType="long" order="BEFORE">
            SELECT TVA_UPSELLADMIN_CHANNEL_SEQ.nextVal from dual
        </selectKey>

into tva_upselladmin_channel (id,source_id, service_id, name) values (#{id}, #{channel.sourceId}, #{channel.serviceId}, #{channel.name})
</foreach>
</insert>

MyBatis in its current version (or anyone for that matter) doesn't allow the use of <selectKey> inside a <forEach> tag. MyBatis在其当前版本(或任何人)中不允许在<forEach>标记内使用<selectKey> Is it only for iterate through a list. 它是否仅用于遍历列表。

The MyBatis dtd validation section for the <foreach> tag is as follow: <foreach>标记的MyBatis dtd验证部分如下:

<!ELEMENT foreach (#PCDATA | include | trim | where | set | foreach | choose | if | bind)*>
<!ATTLIST foreach
collection CDATA #REQUIRED
item CDATA #IMPLIED
index CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
separator CDATA #IMPLIED
>

So in order to solve your problem you have to iterate through your list setting all the ids with an extra select definition on your XML. 因此,为了解决您的问题,您必须遍历列表设置所有ID,并在XML上使用额外的select定义。 It would be like: 这将是:

<select id="nextvalKey" resultType="java.lang.Integer">
     SELECT TVA_UPSELLADMIN_CHANNEL_SEQ.nextVal from dual
</select>

Your insert section would be like: 你的插入部分就像:

<insert id="insertServiceMappings" parameterType="java.util.List">
    <foreach collection="list" item="channel" index="index" >
        INSERT INTO tva_upselladmin_channel (id,source_id, service_id, name)
              VALUES ( #{id}, #{channel.sourceId}, #{channel.serviceId}, #{channel.name});
    </foreach>
</insert>

Don't forget the ; 别忘了; after the insert command because ORACLE does not support multiple values insert eg insert ... values (1,'bla'), (2, 'ble'), (3, 'bli'); 在insert命令之后因为ORACLE不支持多个值插入,例如insert ... values (1,'bla'), (2, 'ble'), (3, 'bli'); )

So the second part is to have in your implementation a method to set each id for the items on the list. 所以第二部分是在你的实现中有一个方法来设置列表中项目的每个id。 It would be something like: 它会是这样的:

  public void someMethodInsertList(List<SomeObject> list){
       //normally I do an implementation that allows me to use
       //sqlSessionTemplate from mybatis through an extended class 
       for ( SomeObject obj : list ){
           obj.setId( getSqlSessionTemplate.selectOne( 'nextvalKey' ) );
       }
       getSqlSessionTemplate.insert( 'insertServiceMappings', list );
  }

Hope it helps 希望能帮助到你

I find another solution as below, it worked for me! 我找到了另一种解决方案,它对我有用!

 <insert id="insertServiceMappings" parameterType="java.util.List" useGeneratedKeys="true">
         <selectKey keyProperty="id" resultType="java.lang.Long" order="BEFORE">
                SELECT TVA_UPSELLADMIN_CHANNEL_SEQ.nextVal as id FROM DUAL
         </selectKey>    
         INSERT INTO
         tva_upselladmin_channel (id,source_id, service_id, name)
         SELECT TVA_UPSELLADMIN_CHANNEL_SEQ.nextVal, A.* from (
         <foreach collection="list" item="channel" index="index" separator="union all">
         SELECT 
           #{channel.sourceId} as source_id,
           #{channel.serviceId} as service_id,
           #{channel.name}) as name
         FROM DUAL
         </foreach> ) A
    </insert>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM