zoukankan      html  css  js  c++  java
  • 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)); } }
  • 相关阅读:
    Mysql任务调度
    使用 IntraWeb (18)
    使用 IntraWeb (17)
    替盛大代发的招聘启示
    使用 IntraWeb (16)
    使用 IntraWeb (15)
    使用 IntraWeb (14)
    使用 IntraWeb (13)
    使用 IntraWeb (12)
    使用 IntraWeb (11)
  • 原文地址:https://www.cnblogs.com/ptqueen/p/8435230.html
Copyright © 2011-2022 走看看