Java MyBatis 插入数据库返回主键
问题?
如何在Java MyBatis 插入数据库返回主键?
最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记。
类似下面这段代码一样获取插入后的主键
User user = new User();
user.setUserName("chenzhou");
user.setPassword("xxxx");
user.setComment("测试插入数据返回主键功能"); System.out.println("插入前主键为:"+user.getUserId());
userDao.insertAndGetId(user);//插入操作
System.out.println("插入后主键为:"+user.getUserId());
解决方案:
由于鄙人当时的学习水平有限,未能很好处理这个问题,如今再来看这个问题,其实很简单。
当时我的思维局限于插入数据后不想再次调用查询接口,就直接获取这个插入的主键Id. 因此如果想达到这种效果,最优方案是下面解决方案的第二种方式。
但是其实我们完全可以在插入后再调用下其他查询接口就可以了。
User user = new User();
user.setUserName("chenzhou");
user.setPassword("xxxx");
user.setComment("测试插入数据返回主键功能"); System.out.println("插入前主键为:"+user.getUserId());
userDao.insertAndGetId(user);//插入操作 User myUser=userDao.findUserByName(user.getName());
System.out.println("插入后主键为:"+myUser.getUserId());
不想再次调用查询接口的解决方案
经过查询网上资料,发现大致有两种方式。
第一种方式:
在实体类的映射文件 "*Mapper.xml" 这样写:
<insert id="insertAndGetId" useGeneratedKeys="true" keyProperty="userId" parameterType="com.chenzhou.mybatis.User">
insert into user(userName,password,comment)
values(#{userName},#{password},#{comment})
</insert>
Tips:
useGeneratedKeys="true" 表示给主键设置自增长keyProperty="userId" 表示将自增长后的Id赋值给实体类中的userId字段。parameterType="com.chenzhou.mybatis.User" 这个属性指向传递的参数实体类 这里提醒下,<insert></insert> 中没有resultType属性,不要乱加。实体类中uerId 要有getter() and setter(); 方法
由于我在MySQL数据库中建表时候已经设置了字段自增长,故最终我选择了第二种方式。
第二种方式:
同样在实体类的映射文件 "*Mapper.xml" 但是要这样写:
<!-- 插入一个商品 -->
<insert id="insertProduct" parameterType="domain.model.ProductBean" >
<selectKey resultType="java.lang.Long" order="AFTER" keyProperty="productId">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO t_product(productName,productDesrcible,merchantId)values(#{productName},#{productDesrcible},#{merchantId});
</insert>
Tips:
<insert></insert> 中没有resultType属性,但是<selectKey></selectKey> 标签是有的。 order="AFTER" 表示先执行插入语句,之后再执行查询语句。 可被设置为 BEFORE 或 AFTER。 如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。 如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素-这和如 Oracle 数据库相似,可以在插入语句中嵌入序列调用keyProperty="userId" 表示将自增长后的Id赋值给实体类中的userId字段。SELECT LAST_INSERT_ID() 表示MySQL语法中查询出刚刚插入的记录自增长Id. 实体类中uerId 要有getter() and setter(); 方法
实现需求,上面那些就足够了。
了解扩展
这里如果有兴趣的,请继续听我讲一个Mybatis中可能误入的坑。 为什么Mybatis 中修改添加方法为有返回值后,虽然提示插入数据库成功并且也能读取插入的数据,但是当你打开数据库后就是看不到插入的数据? 如果在实现上述需求时,想插入后返回主键的话,切记不要这样写。
@Override
public Long insertProduct(ProductBean productBean) {
// TODO Auto-generated method stub
SqlSession session = MybatisJDBCUtil.currentSession(); ProductIDao productIDao = session.getMapper(ProductIDao.class);// 这里*.class
// 必须对应DAO的接口层
return productIDao.insertProduct(productBean); }
Why?
因为如果你是像上面这样写,那么执行后返回的也不是你想要的主键Id,而是执行数据库语句后受影响的行数。
而且,当你执行后你会发现提示插入成功,你用代码也可以读取出插入的数据,但是永远只有一条记录。
并且,你打开数据库会发现,数据库中没有插入成功任何数据。
我在这里郁闷了N久,终于发现了关键所在。
有返回值和没返回值的区别在于:
有返回值的只是对数据库只读模式访问数据库,对数据库数据不会有任何修改,比如各种方式的查询。
无返回值的则会以读写模式访问数据库,会对数据库中的数据进行修改,比如删除,增加。
除此之外,根据个人理解应该mybatis在执行插入语句时会先缓存到构造的一个类似session集合中,然后才去调用底层驱动去操作修改数据库。
session.commit(); MybatisJDBCUtil.closeSession();
没有返回值得才有上面这两条语句,也就是说执行了这两条语句才会真正执行插入到数据库,对数据库的数据进行修改。
相反,有返回值的就没有执行这两条语句,所以只是在自己构造的session中执行了添加语句,但是并没有提交到数据库中,故数据库中是没有任何记录的。
这也就解释了为什么Mybatis 中修改添加方法为有返回值后,虽然提示插入数据库成功,但是当你打开数据库看不到插入的数据。
Mybatis中插入语句方法种不要有返回值,像这样写是正确的。
@Override
public void insertProduct(ProductBean productBean) {
// TODO Auto-generated method stub
SqlSession session = MybatisJDBCUtil.currentSession(); ProductIDao productIDao = session.getMapper(ProductIDao.class);// 这里*.class
// 必须对应DAO的接口层
productIDao.insertProduct(productBean);
session.commit(); MybatisJDBCUtil.closeSession();
}
参考资料一:https://my.oschina.net/crazybird/blog/379635?p=1
参考资料二:http://blog.csdn.net/jbgtwang/article/details/7307687
参考资料三:http://blog.csdn.net/after_you/article/details/53844908
Java MyBatis 插入数据库返回主键的更多相关文章
- Java MyBatis 插入数据库返回主键--insertSelective这样就不用每次到数据库里面查询了
insertSelective---Java MyBatis 插入数据库返回主键--insertSelective这样就不用每次到数据库里面查询了 https://www.cnblogs.com/xi ...
- MyBatis 插入数据库返回主键
最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记. 类似下面这段代码一样获取插入后的主键 User user = new User ...
- mybatis插入数据库 返回主键
传递参数为对象TaskEntity, 返回主键结果为Integer 与 主键 task_id 的类型一致即可 <insert id="addTask" parameterTy ...
- 关于mybatis插入数据库返回主键id
关于Sequence主键的数据库来说,如: <insert id="add" parameterType="vo.Category"> <se ...
- MyBatis框架——mybatis插入数据返回主键(mysql、oracle)
向数据库中插入数据时,大多数情况都会使用自增列或者UUID做为主键.主键的值都是插入之前无法知道的,但很多情况下我们在插入数据后需要使用刚刚插入数据的主键,比如向两张关联表A.B中插入数据(A的主键是 ...
- MyBatis插入语句返回主键值
插入语句xml代码: <insert id="insertUser" parameterType="com.spring.mybatis.po.User" ...
- mybatis插入是返回主键id
<!-- 插入数据:返回记录的id值 --> <insert id="insertOneTest" parameterType="org.chench. ...
- mybatis插入数据返回主键
原来之前一直用错了... keyProperty是表示将返回的主键设置为该方法参数的对应属性中去,而不是用返回值的形式的去获取.
- Mybatis插入数据返回主键ID
<insert id="add" parameterType="com.dsa.core.base.model.ProductSync"> ...
随机推荐
- Android Studio 多个编译环境配置 多渠道打包 APK输出配置
看完这篇你学到什么: 熟悉gradle的构建配置 熟悉代码构建环境的目录结构,你知道的不仅仅是只有src/main 开发.生成环境等等环境可以任意切换打包 多渠道打包 APK输出文件配置 需求 一般我 ...
- .Net Core MVC 网站开发(Ninesky) 2.4、添加栏目与异步方法
在2.3中完成依赖注入后,这次主要实现栏目的添加功能.按照前面思路栏目有三种类型,常规栏目即可以添加子栏目也可以选择是否添加内容,内容又可以分文章或其他类型,所以还要添加一个模块功能.这次主要实现栏目 ...
- UWP学习目录整理
UWP学习目录整理 0x00 可以忽略的废话 10月6号靠着半听半猜和文字直播的补充看完了微软的秋季新品发布会,信仰充值成功,对UWP的开发十分感兴趣,打算后面找时间学习一下.谁想到学习的欲望越来越强 ...
- HTML 事件(一) 事件的介绍
本篇主要介绍HTML中的事件知识:事件相关术语.DOM事件规范.事件对象. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三 ...
- ExtJS 4.2 第一个程序
本篇介绍如何创建一个ExtJS应用程序.并通过创建目录.导入文件.编写代码及分析代码等步骤来解释第一个ExtJS程序. 目录 1. 创建程序 1.1 创建目录建议 1.2 实际目录 1.3 index ...
- 【原】AFNetworking源码阅读(二)
[原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...
- mybatis_基础篇
一.认识mybatis: MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改 ...
- iOS UITableView 与 UITableViewController
很多应用都会在界面中使用某种列表控件:用户可以选中.删除或重新排列列表中的项目.这些控件其实都是UITableView 对象,可以用来显示一组对象,例如,用户地址薄中的一组人名.项目地址. UITab ...
- MyBatis源码分析(二)语句处理器
StatementHandler 语句处理器,主要负责语句的创建.参数的设置.语句的执行.不负责结果集的处理. Statement prepare(Connection connection, Int ...
- CSS3自定义滚动条样式 -webkit-scrollbar(转)
有没有觉得浏览器自带的原始滚动条很不美观,同时也有看到很多网站的自定义滚动条显得高端,就连chrome32.0开发板都抛弃了原始的滚动条,美观多了.那webkit浏览器是如何自定义滚动条的呢? 前言 ...