MyBatis将batchGeneratedKeys用于批量插入

时间:2017-02-10 13:32:23

标签: mysql mybatis spring-mybatis

批量插入并获取生成的密钥时,获取错误。 批量插入工作正常。

对象结构:

对象1:

Long id, String name, Obj2 obj 

对象2:(Obj2)

Long id, String value

两个对象都存储在不同的表中。

object1

id | name  | object2_id (Foreign Key)

object2

id | value

现在我有一个对象1 列表要插入。

该过程将插入对象2 获取ID,并将对象1 插入 Object2的 id (作为外键)。

插入 Object2 时,Mapper.xml中的插入块

案例1:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj1s.obj2.id">
<!-- obj1s is name of the list --> 
    insert into object2 (value) values 
        <foreach collection="obj1s" item="obj1" separator=",">
            (#{obj1.obj2.id})
        </foreach>
</insert>
  

错误:获取生成密钥或将结果设置为参数对象时出错。

案例2:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj1.obj2.id">
<!-- obj1 so as to access the object of foreach loop --> 
    insert into object2 (value) values 
        <foreach collection="obj1s" item="obj1" separator=",">
            (#{obj1.obj2.id})
        </foreach>
</insert>
  

错误:获取生成密钥或将结果设置为参数对象时出错。原因:org.apache.ibatis.binding.BindingException:找不到参数'obj1'。可用参数是[obj1s,param1]

案例3:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj2.id">
<!-- obj2 is the object with variable id to store generated key --> 
    insert into object2 (value) values 
        <foreach collection="obj1s" item="obj1" separator=",">
            (#{obj1.obj2.id})
        </foreach>
</insert>
  

错误:获取生成密钥或将结果设置为参数对象时出错。原因:org.apache.ibatis.binding.BindingException:找不到参数'obj2'。可用参数是[obj1s,param1]

反正有没有实现这个目标? 可能使用 selectKey ,但selectkey用于不支持自动生成密钥的DB。

使用MyBatis 3.3.1和Mysql。

2 个答案:

答案 0 :(得分:10)

所以,我明白了。 MyBatis存在多行插入和useGenerated密钥的错误。在进行批量插入和获取生成密钥时,Bug是列表变量名称必须是&#34; list&#34; 。然后相应地访问该对象。因此,对于上面的示例,代码将如下所示:

<insert id="batchInsert" parameterType="list" useGeneratedKeys="true" keyProperty="obj2.id">
<!-- obj2 is the object with variable id to store generated key --> 
insert into object2 (value) values 
    <foreach collection="list" item="obj1" separator=",">
        (#{obj1.obj2.id})
    </foreach>

并且mapper.java方法声明将如下所示:

public Integer batchInsert(@Param("list")List<Obj1> obj1);

变量名称必须为列表。没别了。

感谢@blackwizard,我重新审视并检查了这个错误,让我得到了这个答案。

答案 1 :(得分:0)

您必须访问obj.id obj 是属性名称, Obj2 是类型名称。

此外,检索生成的键有效/仅对单个插入有意义。 确实:您想插入N条记录,但您的代码将生成并执行单个(巨型)语句。这不是批处理。

在Java中迭代你的列表,在循环中调用更简单的insert语句(不再是foreach),然后每个生成的键都可以绑定到匹配的对象。 使用ExecutorType.REUSE打开SqlSession,这样语句只准备一次,每次迭代都只发送参数。

我已经回答this kind of question