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)); } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM