MyBatis——insert并返回主键ID解决方案
问题描述
添加记录后获取主键ID,这是一个很常见的需求,特别是在一次前端调用中需要插入多个表的场景。
除了添加单条记录时获取主键值,有时候可能需要获取批量添加记录时各记录的主键值。
问题分析
暂无。
解决方案
MyBatis从3.3.1版本开始支持批量添加记录并返回各记录主键字段值。
添加单一记录时返回主键ID
添加一条记录时返回主键值,在xml映射器和接口映射器中都可以实现。
在映射器中配置获取记录主键值
XML映射器
在定义xml映射器时设置属性useGeneratedKeys值为true,并分别指定属性keyProperty和keyColumn为对应的数据库记录主键字段与Java对象的主键属性。
<mapper namespace="org.chench.test.mybatis.mapper"><!-- 插入数据:返回记录主键id值 --><insert id="insertOneTest" parameterType="org.chench.test.mybatis.model.Test" useGeneratedKeys="true" keyProperty="id" keyColumn="id" >insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())</insert> </mapper>
接口映射器
在接口映射器中通过注解
@Options
分别设置参数useGeneratedKeys,keyProperty,keyColumn值// 返回主键字段id值 @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") @Insert("insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())") Integer insertOneTest(Test test);
获取新添加记录主键字段值
需要注意的是,在MyBatis中添加操作返回的是记录数并非记录主键id。因此,如果需要获取新添加记录的主键值,需要在执行添加操作之后,直接读取Java对象的主键属性。
Integer rows = sqlSession.getMapper(TestMapper.class).insertOneTest(test);
System.out.println("rows = " + rows); // 添加操作返回记录数
System.out.println("id = " + test.getId()); // 执行添加操作之后通过Java对象获取主键属性值
添加批量记录时返回主键ID
如果执行批量添加并返回各记录主键字段值,只能在XML映射器中实现,在接口映射器中无法实现。
<!-- 批量添加数据,并返回主键字段 -->
<insert id="insertBatchTest" useGeneratedKeys="true" keyProperty="id">INSERT INTO test(name,descr,url,create_time,update_time) VALUES<foreach collection="list" separator="," item="t">(#{t.name},#{t.descr},#{t.url},now(),now())</foreach>
</insert>
注:执行批量添加并返回记录主键值的XML映射器配置,跟添加单条记录时是一致的。不同的地方仅仅是使用了foreach元素构建批量添加语句。
实现原理
需要注意的是,不论在XML映射器还是在接口映射器中,添加记录的主键值并非添加操作的返回值。
实际上,在MyBatis中执行添加操作时只会返回当前添加的记录数。
package org.apache.ibatis.executor.statement;
public class PreparedStatementHandler extends BaseStatementHandler {@Overridepublic int update(Statement statement) throws SQLException {PreparedStatement ps = (PreparedStatement) statement;// 真正执行添加操作的SQL语句ps.execute();int rows = ps.getUpdateCount();Object parameterObject = boundSql.getParameterObject();KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();// 在执行添加操作完毕之后,再处理记录主键字段值keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);// 添加记录时返回的是记录数,而并非记录的主键字段值return rows;}
}
MyBatis insert操作的时序图:
跟踪时序图执行步骤可以看到,MyBatis最终是通过MySQL驱动程序获取到了新添加的记录主键值。
参考文章
https://www.cnblogs.com/nuccch/p/9067305.html
https://github.com/mybatis/mybatis-3/pull/350 Support insert multiple rows and write-back id.More about insert multipl...
https://www.zhihu.com/question/21153827 mybatis 批量插入如何返回每个条记录的自生成主键?
https://blog.csdn.net/jiangeeq/article/details/55047116 Mybatis批量插入返回插入成功后的主键id
https://blog.csdn.net/top_code/article/details/52404345 MyBatis 3.3.1 批量插入多行回写自增id
MyBatis——insert并返回主键ID解决方案相关推荐
- MyBatis—insert语句返回主键和selectKey标签
本文已同步至个人博客liaosi's blog - MyBatis-insert语句返回主键和selectKey标签 往数据库中插入一条记录后,有时候我们需要这条记录的主键,用于后续的操作.如果在插入 ...
- 使用mybatis plus添加返回主键id
使用mybatis plus时返回的主键id,返回的数据是1515287203954688002的,这显然不是我想要的 orderDAO.insert(orderDO); return orderDO ...
- 160613、MyBatis insert操作返回主键
在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能,针对Sequence主键而言,在执行 ...
- MyBatis insert操作返回主键
在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能 针对Sequence主键而言,在执行 ...
- Mybatis批量插入,返回主键ID不成功,巨坑
一.场景说明 批量插入,返回主键ID报错 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibati ...
- mybatis添加记录时返回主键id
参考:mybatis添加记录时返回主键id 场景 有些时候我们在添加记录成功后希望能直接获取到该记录的主键id值,而不需要再执行一次查询操作. 在使用mybatis作为ORM组件时,可以很方便地达到这 ...
- 使用mybatis插入数据(insert)时返回主键的问题
使用mybatis做插入操作时,想要获取新增记录的主键,我发现现在的方式和以前的方式有所区别,即以前是直接通过方法返回,现在是将主键设置在数据实体对象中. 下面对mybatis进行insert时返回主 ...
- mybatis 主键自增 insert后返回主键
mybatis 主键自增 insert后返回主键 : <insert id="insertStudentAutoKey" parameterType="Studen ...
- Mybatis执行插入语句后并返回主键ID
我们知道JDBC可以实现插入语句后返回主键Id,那mybatis可以实现吗?答案是肯定的. 1.MySQL数据库设置ID自增情况 <insert id="insertUser" ...
最新文章
- Spark:如何替换sc.parallelize(List(item1,item2)).collect().foreach(row={})为并行?
- Android 监听APP进入前台、后台
- 腾讯地图api修改信息窗口样式_DOTA2 地图编辑器指南(二):总览
- Kinect2.0-空间长度测量
- 同一条sql在mysql5.6和5.7版本遇到的问题。
- mysql------explain工具
- 关于Relay Log无法自动删除的问题
- poj 2356 Find a multiple dfs 爆搜!!!!
- 织梦安全的思路---未实践
- 张朝阳:走出焦虑,不再焦虑
- Fabric开发(三) Ubuntu20.04.1快速搭建Fabric1.4.3 (排雷版)
- 遥感影像的特征空间图
- CSS基础常识问答(四)
- 新建web.xml文件头报错报红xmlns=http://xmlns.jcp.org/xml/ns/javaee,http://xmlns.jcp.org/xml/ns/javaee/web-ap
- VC中常见的108个问题
- CentOS配置Jenkins+Android+fir+pyger(蒲公英)+qiniu(七牛)
- win10卸载WSL2记录
- PX4多传感器优先级判断
- 一个女程序员职场自述:彻骨的孤独
- WinGate 6.0 build 984铪铪铪
热门文章
- 程序员的.NET时代
- c# 睡眠3秒_C#中的闭包和意想不到的坑
- oracle xmltype使用,oracle的xmltype基本使用有哪些呢?
- java打包后发布找不到jsp_eclipse中web项目部署以后jsp的java文件找不到问题(Tomcat配置serverlocations)...
- html批量翻译 github,英文单词短语批量翻译工具WordListTranslator
- springboot 前缀_SpringBoot配置文件的注入
- 数据结构与算法(四):二叉树
- c语言中的数字菱形,打印数字菱形,急啊,帮帮小女子啊。。。
- 画出该lti系统的幅频特性响应曲线_一文带你通俗理解幅频响应和相频响应
- java jpa hibernate_java - JPA和Hibernate - Criteria与JPQL或HQL