MyBatis useGeneratedKeys 批量插入嵌套对象
MyBatis useGeneratedKeys for nested object in batch insert
批量插入和获取生成的key时,报错。
批量插入工作正常。
对象结构:
对象 1:
Long id, String name, Obj2 obj
对象 2:(Obj2)
Long id, String value
两个对象都存储在不同的表中。
Table object1
id | name | object2_id (Foreign Key)
Table object2
id | value
现在我有一个要插入的 对象 1 的列表。
进程会insert Object 2获取id,insert Object 1 with " id " of Object2(作为外键)。
在插入Object2时,插入块在Mapper.xml
案例一:
<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>
ERROR: Error getting generated key or setting result to parameter object.
案例二:
<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>
ERROR: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'obj1' not found. Available parameters are [obj1s, param1]
案例三:
<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>
ERROR: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'obj2' not found. Available parameters are [obj1s, param1]
有什么办法可以实现吗?
可能使用 selectKey,但 selectkey 用于不支持自动生成密钥的数据库。
使用 MyBatis 3.3.1 和 Mysql。
您必须访问obj.id
,obj是属性名称,Obj2是类型名称。
此外,检索生成的密钥 works/makes 仅适用于单个插入。
确实:您想插入 N 条记录,但您的代码将生成并执行单个(巨大的)语句。这不是批处理。
遍历 Java 中的列表,在循环中调用更简单的插入语句(不再有 foreach),然后每个生成的键都可以绑定到匹配的对象。
使用 ExecutorType.REUSE 打开 SqlSession,这样语句只准备一次,每次迭代只发送参数。
我已经回答了this kind of question。
所以,我想通了。 multi-row 插入和使用生成的密钥时,MyBatis 存在这个错误。 Bug 是列表变量名称 必须是 "list" 进行批量插入并获取生成的密钥时。然后相应地访问对象。所以对于上面的示例,代码将如下所示:
<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);
变量名必须是list。没有别的。
感谢@blackwizard,我重新审视并检查了这个错误,这让我找到了这个答案。
批量插入和获取生成的key时,报错。 批量插入工作正常。
对象结构:
对象 1:
Long id, String name, Obj2 obj
对象 2:(Obj2)
Long id, String value
两个对象都存储在不同的表中。
Table object1
id | name | object2_id (Foreign Key)
Table object2
id | value
现在我有一个要插入的 对象 1 的列表。
进程会insert Object 2获取id,insert Object 1 with " id " of Object2(作为外键)。
在插入Object2时,插入块在Mapper.xml
案例一:
<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>
ERROR: Error getting generated key or setting result to parameter object.
案例二:
<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>
ERROR: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'obj1' not found. Available parameters are [obj1s, param1]
案例三:
<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>
ERROR: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.binding.BindingException: Parameter 'obj2' not found. Available parameters are [obj1s, param1]
有什么办法可以实现吗? 可能使用 selectKey,但 selectkey 用于不支持自动生成密钥的数据库。
使用 MyBatis 3.3.1 和 Mysql。
您必须访问obj.id
,obj是属性名称,Obj2是类型名称。
此外,检索生成的密钥 works/makes 仅适用于单个插入。 确实:您想插入 N 条记录,但您的代码将生成并执行单个(巨大的)语句。这不是批处理。
遍历 Java 中的列表,在循环中调用更简单的插入语句(不再有 foreach),然后每个生成的键都可以绑定到匹配的对象。 使用 ExecutorType.REUSE 打开 SqlSession,这样语句只准备一次,每次迭代只发送参数。
我已经回答了this kind of question。
所以,我想通了。 multi-row 插入和使用生成的密钥时,MyBatis 存在这个错误。 Bug 是列表变量名称 必须是 "list" 进行批量插入并获取生成的密钥时。然后相应地访问对象。所以对于上面的示例,代码将如下所示:
<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);
变量名必须是list。没有别的。
感谢@blackwizard,我重新审视并检查了这个错误,这让我找到了这个答案。