mybatis批量插入数据返回主键
2018-03-21 10:31
330 查看
Mybatis在执行批量插入时,如果使用的是for循环逐一插入,那么可以正确返回主键id。如果使用动态sql的foreach循环,那么返回的主键id列表,可能为null,这让很多人感到困惑;本文将分析问题产生的原因,并修复返回主键id为null的问题。该问题在开源中国社区,以及网络上,已经有很多人遇到并发帖咨询,似乎都没有得到期望的解决结果。今天,我将带领大家,分析并解决该问题,让foreach批量插入,返回正确的id列表。
以上便是Mybatis的foreach循环,其要生成的sql语句是:insert into students(stud_id, name) values(?, ?),(?, ?), (?, ?); 类似这样的批量插入。
Mybatis是对Jdbc的封装,我们来看看,Jdbc是否支持上述形式的批量插入,并返回主键id列表的。
Output:
好了,事实证明,Jdbc是支持上述批量插入,并能正确返回id列表的。Jdbc都支持,如果Mybatis却不支持,有点说不过去。
1. Mapper.xml中keyProperty和parameterType属性之间的关系(很重要)
上述xml配置,含义为,属性studId是参数类型Student对象的主键属性。毫无疑问,Student对象中有studId属性。
那这个如何解释呢?ArrayList有studId属性吗?当然没有了。其正确含义为:ArrayList集合中的元素的studId属性。
所以,keyProperty和parameterType之间的关系,有时是直接关系,有时是间接关系。明白这个道理之后,我们就可以开始进一步阅读源码了。
详情:参考https://my.oschina.net/zudajun/blog/674946,http://www.cnblogs.com/admol/articles/4248159.html
示例:
向orderitem里面批量插入数据
<insert id="addOrderitem" useGeneratedKeys="true" keyProperty="oid"
parameterType="java.util.ArrayList">
insert into orderitem(iid,count,subtotal,oid,bid)
values
<foreach collection="list" item="item" index="index"
separator=",">
(#{item.iid},#{item.count},#{item.subtotal},#{item.orders.oid},
#{item.bid})
</foreach>
</insert>
写成#{item.orders.oid}的原因如下
public class orderitem {
private int iid;
private int count;
private double subtotal;
private orders orders;
private book book;
/**}
public class orders {
private int oid;
private Date ordertime;
private double total;
private int state;
private int uid;
private user owner;
private List<orderitem> orderitem;
---
}
<insert id="insertStudents" useGeneratedKeys="true" keyProperty="studId" parameterType="java.util.ArrayList"> INSERT INTO STUDENTS(STUD_ID, NAME, EMAIL, DOB, PHONE) VALUES <foreach collection="list" item="item" index="index" separator=","> (#{item.studId},#{item.name},#{item.email},#{item.dob}, #{item.phone}) </foreach> </insert>
以上便是Mybatis的foreach循环,其要生成的sql语句是:insert into students(stud_id, name) values(?, ?),(?, ?), (?, ?); 类似这样的批量插入。
Mybatis是对Jdbc的封装,我们来看看,Jdbc是否支持上述形式的批量插入,并返回主键id列表的。
PreparedStatement pstm = conn.prepareStatement("insert into students(name, email) values(?, ?), (?, ?), (?, ?)", Statement.RETURN_GENERATED_KEYS); pstm.setString(1, "name1"); pstm.setString(2, "email1"); pstm.setString(3, "name2"); pstm.setString(4, "email2"); pstm.setString(5, "name2"); pstm.setString(6, "email2"); pstm.addBatch(); pstm.executeBatch(); ResultSet rs = pstm.getGeneratedKeys(); while (rs.next()) { Object value = rs.getObject(1); System.out.println(value); }
Output:
248 249 250
好了,事实证明,Jdbc是支持上述批量插入,并能正确返回id列表的。Jdbc都支持,如果Mybatis却不支持,有点说不过去。
1. Mapper.xml中keyProperty和parameterType属性之间的关系(很重要)
useGeneratedKeys="true" keyProperty="studId" parameterType="Student"
上述xml配置,含义为,属性studId是参数类型Student对象的主键属性。毫无疑问,Student对象中有studId属性。
useGeneratedKeys="true" keyProperty="studId" parameterType="java.util.ArrayList"
那这个如何解释呢?ArrayList有studId属性吗?当然没有了。其正确含义为:ArrayList集合中的元素的studId属性。
所以,keyProperty和parameterType之间的关系,有时是直接关系,有时是间接关系。明白这个道理之后,我们就可以开始进一步阅读源码了。
详情:参考https://my.oschina.net/zudajun/blog/674946,http://www.cnblogs.com/admol/articles/4248159.html
<!-- 批量插入生成的兑换码 --> 2 <insert id ="insertCodeBatch" parameterType="java.util.List" > 3 <selectKey resultType ="java.lang.Integer" keyProperty= "id" 4 order= "AFTER"> 5 SELECT LAST_INSERT_ID() 6 </selectKey > 7 insert into redeem_code 8 (bach_id, code, type, facevalue,create_user,create_time) 9 values 10 <foreach collection ="list" item="reddemCode" index= "index" separator =","> 11 ( 12 #{reddemCode.batchId}, #{reddemCode.code}, 13 #{reddemCode.type}, 14 #{reddemCode.facevalue}, 15 #{reddemCode.createUser}, #{reddemCode.createTime} 16 ) 17 </foreach > 18 </insert >
示例:
向orderitem里面批量插入数据
<insert id="addOrderitem" useGeneratedKeys="true" keyProperty="oid"
parameterType="java.util.ArrayList">
insert into orderitem(iid,count,subtotal,oid,bid)
values
<foreach collection="list" item="item" index="index"
separator=",">
(#{item.iid},#{item.count},#{item.subtotal},#{item.orders.oid},
#{item.bid})
</foreach>
</insert>
写成#{item.orders.oid}的原因如下
public class orderitem {
private int iid;
private int count;
private double subtotal;
private orders orders;
private book book;
/**}
public class orders {
private int oid;
private Date ordertime;
private double total;
private int state;
private int uid;
private user owner;
private List<orderitem> orderitem;
---
}
相关文章推荐
- 数据库插入数据返回当前自增主键ID值的方法
- Mybatis批量插入返回插入成功后的主键id
- JdbcTemplate下访问Oracle数据库插入数据时返回序列增长的主键
- spring JdbcTemplate下访问Oracle数据库插入数据时返回序列增长的主键
- mybatis 插入数据时返回主键
- JdbcTemplate下访问Oracle数据库插入数据时返回序列增长的主键
- Mybatis配置插入数据返回主键ID
- SqlServer2005配置mybatis3.0插入数据返回该数据的主键
- Sql Server 插入数据的同时返回插入数据的ID/主键信息
- JDBC 插入数据返回数据主键
- Mybatis+MySql 插入数据后返回自增主键值
- jdbc:mysql和oracle插入一条数据返回主键
- Mybatis_插入数据后返回主键ID_返回数据字段与类中字段相对应
- mybatis插入数据后返回插入记录的主键
- MyBatis框架——mybatis插入数据返回主键(mysql、oracle)
- Mybatis中,当插入数据后,返回最新主键id的几种方法,及具体用法
- 使用Mybatis时,在插入一条数据记录返回主键id值
- MyBatis与Oracle,MySql,SqlServer插入数据返回主键方式
- 数据库插入数据返回当前主键ID值方法
- mybatis mysql 插入对象返回数据主键id