mybatis获取insert插入之后的id
一.为什么要获取insert的id
写了测试类测试插入,插入之后用select查询出来进行Assert
插入成功后,不管Select对比的结果成功还是失败,都希望删除掉测试插入的结果
二.运行环境
mysql自增主键
mapper中的insert下是,这是通过mybatis_generator自动生成的,最新版本1.3.6.
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Long">
SELECT LAST_INSERT_ID()
</selectKey>
然后
goodsClassService.insertGoodsClass(goodsclass);
但是用断点调试发现goodsclass的id一直是0,这让我不得其解.
三.原因
感觉Mybatis的这个自动生成的xml有问题.
参考:http://blog.csdn.net/slvher/article/details/42298355
6. last_insert_id()的值是由MySQL server来维护的,而且是为每条连接维护独立的值,也即,某条连接调用last_insert_id()获取到的值是这条连接最近一次insert操作执行后的自增值,该值不会被其它连接的sql语句所影响。这个行为保证了不同的连接能正确地获取到它最近一次insert sql执行所插入的行的自增值,也就是说,last_insert_id()的值不需要通过加锁或事务机制来保证其在多连接场景下的正确性。
mybatis的连接和客户端,比如workbench连接不同,last_insert_id()不能进行比较.
每一次测试运行都是新的连接,所last_insert_id()都是0,
mybatis默认生成的selectKey是在before之前,手动插入id为0,
如果给自增列插入0或者null,那么自增列设置为根据当前最大的id+1
如果批量插入就有问题了
Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '66671' for key 'PRIMARY'
第一次插入id是0,可以自增.因为用了连接池,即使关闭了sqlsession也可能是同一个连接,第二次插入取出了last_insert_id()为66671,再插入,重复id错误.
三.解决办法
将上面的改为
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
SELECT LAST_INSERT_ID()
</selectKey>
这是插入之后取出SELECT LAST_INSERT_ID(),插入的时候id默认不插入,mysql会自动帮我们自增.
插入之后二中的goodsclass的id就变为last_id,可以取出来用了.
所以我觉得mybatis_generator这个配置操作有点小bug的
四.测试代码
省略了部分Assert代码
插入成功后,无论查询对比失败或者成功,都将插入的数据删掉.
//测试添加商品分类
//isok()返回状态码200
@Test
public void test_add_goodsClass() throws Exception
{
//测试插入是否成功
String ret=mockMvc.perform(post("/goods_class/add")
.param("pid","1"))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString();
ObjectMapper objectMapper=new ObjectMapper();
Map<String,String> map=objectMapper.readValue(ret,Map.class);
Assert.assertNotNull(map);
Long last_insert_id=Long.valueOf(map.get("id"));
Assert.assertNotEquals(last_insert_id,Long.valueOf(0));
try {
//测试插入结果
Goodsclass goodsclass= goodsClassService.getGoodsClassById(last_insert_id);
Assert.assertEquals(goodsclass.getParent().getId(),Long.valueOf(1)); }
finally {
goodsClassService.deleteGoodsClassById(last_insert_id);
Assert.assertNull(goodsClassService.getGoodsClassById(last_insert_id));
} }
mybatis获取insert插入之后的id的更多相关文章
- myBatis获取批量插入数据的主键id
在myBatis中获取刚刚插入的数据的主键id是比较容易的 , 一般来说下面的一句话就可以搞定了 , 网上也有很多相关资料去查. @Options(useGeneratedKeys = true, k ...
- mybatis获取刚刚插入到数据库的数据的id(转载)
原文地址:https://blog.csdn.net/hehuihh/article/details/82800739 我用的是第一种写法,直接把代码copy到insert标签里(id要是自增id) ...
- 如何在dapper中获取刚插入行的ID
二话不说: 1.先建立个表 CREATE TABLE [dbo].[UserInfo]( [ID] [int] IDENTITY(1,1) NOT NULL, [UserName] [nc ...
- SQL Server output子句用法 output inserted.id 获取刚插入数据的id
--插入数据,并返回刚刚插入的数据id INSERT INTO [soloreztest] ([name]) output inserted.id VALUES ('solorez') --执行结果: ...
- YII获取刚插入数据的id主键
单条数据时model->attributes['id']; 循环插入时使用 Yii::app()->db->getLastInsertID() 获取 循环插入时需要每次插入后重置 m ...
- Mybatis中insert返回主键ID
记录解决的过程,这里就不搬砖了. 1.获取insert后的主键id 原文链接:http://www.cnblogs.com/fsjohnhuang/p/4078659.html 2.insert后返回 ...
- MyBatis在insert插入操作时返回主键ID的配置
在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过Mapper.XML配置的方式来完成这个功能. 在 INSER ...
- mybatis获取批量插入的主键自增id
一.写一个实体类 public class UserInfo { private long userId; private String userAccount; private String use ...
- mybatis 获取insert返回的主键
在我们开发过程中,在插入数据到数据库时,很多时候都需要把其主键返回,这里就说一下mybatis是怎么获取的. 其中mysql和oracle是不同的做法,因为mysql本身就提供字段自增的属性,而ora ...
随机推荐
- html5 css练习 定位布局
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- [批处理]守护NodeJS进程
背景: 日常进行CI过程中,使用NodeJs方式:GIT更新->检测是否需要编译->调用IncrediBuilder编译->读取编译日志判断是否通过->调用7z打包 问题: 持 ...
- 微信扫描二维码安卓弹出默认浏览器(苹果打开App Store)打开下载链接
使用微信推广的用户经常都会遇到推广链接被拦截导致无法下载app的情况,此时用户在微信中打开会提示“ 已停止访问该网页 ”.这对于使用微信营销的商家来说就很不友好且损失非常大,因为用户是不知道为什么打不 ...
- 用Python3实现的Mycin专家系统简单实例
from sys import stderr ######################### TRUE = 1 #定义返回值 FALSE = 0 FACT_LENGTH = 9 #'''前提与结论 ...
- Tensorflow object detection API ——环境搭建与测试
1.开发环境搭建 ①.安装Anaconda 建议选择 Anaconda3-5.0.1 版本,已经集成大多数库,并将其作为默认python版本(3.6.3),配置好环境变量(Anaconda安装则已经配 ...
- Spring:容器基本用法
bean是Spring 最核心的东西,打个比方,假设Spring是一个水桶,那么bean就是水桶里的水,水桶离开水后,就没啥作用了.我们先来看一下bean的定义: public class Perso ...
- 为什么做java开发的公司需要那么多程序员?
注:文章转载自知乎 透过现象看本质. Java是企业应用市场的王者,如果一家非互联网公司用Java,那么十有八九是做企业应用的. 所以,这个问题本质上是:为什么做企业应用的公司需要那么多Java程序员 ...
- window.onload
window.onload事件 window.onload = function () { JS代码块} 当页面中的DOM节点(元素)都加载完的时候执行的JS代码
- MTK(android init.rc) 写一个开机启动的服务
在开机往往我们想要做一些初始化的操作,这时候可以使用init.rc文件来实现,当然书写一个开机启动的服务也需要规范的. 假设是C程序,则需要准备C程序的源码,在我的例程中是一个在开机完成(androi ...
- P4859 已经没有什么好害怕的了(dp+二项式反演)
P4859 已经没有什么好害怕的了 啥是二项式反演(转) 如果你看不太懂二项式反演(比如我) 那么只需要记住:对于某两个$g(i),f(i)$ ---------------------------- ...