一.为什么要获取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的更多相关文章

  1. myBatis获取批量插入数据的主键id

    在myBatis中获取刚刚插入的数据的主键id是比较容易的 , 一般来说下面的一句话就可以搞定了 , 网上也有很多相关资料去查. @Options(useGeneratedKeys = true, k ...

  2. mybatis获取刚刚插入到数据库的数据的id(转载)

    原文地址:https://blog.csdn.net/hehuihh/article/details/82800739 我用的是第一种写法,直接把代码copy到insert标签里(id要是自增id) ...

  3. 如何在dapper中获取刚插入行的ID

    二话不说: 1.先建立个表 CREATE TABLE [dbo].[UserInfo](    [ID] [int] IDENTITY(1,1) NOT NULL,    [UserName] [nc ...

  4. SQL Server output子句用法 output inserted.id 获取刚插入数据的id

    --插入数据,并返回刚刚插入的数据id INSERT INTO [soloreztest] ([name]) output inserted.id VALUES ('solorez') --执行结果: ...

  5. YII获取刚插入数据的id主键

    单条数据时model->attributes['id']; 循环插入时使用 Yii::app()->db->getLastInsertID() 获取 循环插入时需要每次插入后重置 m ...

  6. Mybatis中insert返回主键ID

    记录解决的过程,这里就不搬砖了. 1.获取insert后的主键id 原文链接:http://www.cnblogs.com/fsjohnhuang/p/4078659.html 2.insert后返回 ...

  7. MyBatis在insert插入操作时返回主键ID的配置

    在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过Mapper.XML配置的方式来完成这个功能. 在 INSER ...

  8. mybatis获取批量插入的主键自增id

    一.写一个实体类 public class UserInfo { private long userId; private String userAccount; private String use ...

  9. mybatis 获取insert返回的主键

    在我们开发过程中,在插入数据到数据库时,很多时候都需要把其主键返回,这里就说一下mybatis是怎么获取的. 其中mysql和oracle是不同的做法,因为mysql本身就提供字段自增的属性,而ora ...

随机推荐

  1. JavaFX-Stage

    1.Stage类继承自Window类,继承了Window类的show()方法,Stage的close()方法实际上是调用了继承自Window类的hide()方法.另外还有Window的setOpaci ...

  2. 示例, linq分组

    public class HIS_CLIREGISTER : BaseModel{ private String _FBCODE;[StringLength(8)]/// <summary> ...

  3. PHP百度AI的OCR图片文字识别

    第一步可定要获取百度的三个东西 要到百度AI网站(http://ai.baidu.com/)去注册 然后获得 -const APP_ID = '请填写你的appid'; -const API_KEY ...

  4. react小知识点

    1.render函数什么时候会执行? 当this.state/this.props发生改变的时候render函数就会执行 2.组件第一次执行的时候会执行哪些生命周期 constructor--> ...

  5. lnmp 系统500 报错

    分析点: 1 文件目录权限不足 如果日志缓存目录没有写入权限 chmod -R 775 目录 2 lnmp 一键安装包 查看.user.ini ,其中open_basedir  不要设置到public ...

  6. 多态 鸭子类型 反射 内置方法(__str__,__del__) 异常处理

    ''' 1什么是多态 多态指的是同一种/类事物的不同形态 2 为何要有多态 多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下而直接使用对象 多态性的精髓:统一 多态性的好处: 1增加了程序的 ...

  7. PreparedStatement传进null值报错

    最近在测试jdbc数据导入大量数据的性能,发现PreparedStatement传进null值会报错. 解决方法: setObject(int parameterIndex, Object x, in ...

  8. 洲阁筛 & min_25筛学习笔记

    洲阁筛 给定一个积性函数$F(n)$,求$\sum_{i = 1}^{n}F(n)$.并且$F(n)$满足在素数和素数次幂的时候易于计算. 显然有: $\sum_{i = 1}^{n} F(n) = ...

  9. Pycharm在运行过程中,查看每个变量的方法(show variables)跟终端一样显示变量

    点击运行栏的这个灰色向下剪头: 在出现的窗口上,勾选上: 点击OK,重启Pycharm:接着点击Run窗口: 将Run的show variables图标勾选: 然后你就会发现,在右边出现了变量的窗口:

  10. [十二省联考2019]异或粽子 01trie

    [十二省联考2019]异或粽子 01trie 链接 luogu 思路 首先求前k大的(xo[i]^xo[j])(i<j). 考场上只想到01trie,不怎么会写可持久,就写了n个01trie,和 ...