mybatis uuid主鍵 auto_increment列 回顯id keyGenerator

背景

我們的系統是使用的tk.mybatis,原來線上的一個表用的uuid主鍵。來了一個業務需求,需要新增一個自增的索引列(ALTER TABLEtestADD COLUMNuniq_indexBIGINT AUTO_INCREMENT UNIQUE COMMENT '自增索引';

增加了這個列之後,調用insert(object)插入方法,會將傳入的對象的id回顯(object.id=自增id);

然而,我們期望的是回顯主鍵uuid(線上邏輯),但是實際上回顯的是自增id,不符合需求,會導致bug。

參考作者的文檔

https://github.com/mybatis-book/book/issues/45

單步調試

從insert開始一步一步地往裏走
在這裏插入圖片描述

在這裏插入圖片描述

應該就是這個後置處理的時候會回寫id
在這裏插入圖片描述
回頭看發現是這裏產生的generatedkey
在這裏插入圖片描述

通過參考作者寫的文檔:https://github.com/abel533/Mapper/wiki/2.3-generatedvalue

我們發現生成的key有一個優先級順序

我們原先是用的是一個類來實現,是最低優先級的。
在這裏插入圖片描述
使用這種key生成方法,會在我們不傳入key的情況下,自動用我們指定的類來生成id。
但是,這種方法,會導致我們在有一個自增id的列的情況下,會把自增id填充到我們insert傳入的對象的id,這個其實是不符合預期的,我們還是希望返回的id是uuid的id。

爲了解決這個問題,參考上面的文檔,可以做下面的註解,使用sql語句在插入前生成一個uuid,然後作爲key插入。這樣就可以解決上述的問題。
在這裏插入圖片描述

在這裏插入圖片描述

使用新的配置之後,會在prepareStatement的時候,利用我們配置sql查詢到uuid,作爲id用於插入數據庫

在這裏插入圖片描述

然後進入一個好深的調用棧,最終調用我們定義的sql語句獲取id
在這裏插入圖片描述

如果是原來的配置爲啥就會把id給改了,是哪裏導致代碼執行邏輯不一致呢?
我們把配置改回原來的樣子:使用自定義的類生成id
在這裏插入圖片描述

再單步調試走一遍
發現keyGenerator不是一樣的:
在這裏插入圖片描述

找到兇手!
在這裏插入圖片描述
當我們走這個配置genId=xxx.class的時候,keyGenerator是 Jdbc3KeyGenerator 這個在processBefore函數裏啥也不幹;在processAfter函數裏會調用populateKeys,將id給覆蓋掉!

當我們走配置@KeySql(sql = "select REPLACE(uuid(),'-','')", order = ORDER.BEFORE) 的時候, keyGenerator是selectKeyGenerator,而他的processAfter函數就不會有populateKeys這種邏輯,所以就不會把id覆蓋掉了~
在這裏插入圖片描述

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章