1. 程式人生 > 其它 >關於雪花ID自動生成和Tk.mybatis的問題

關於雪花ID自動生成和Tk.mybatis的問題

技術標籤:javamybatis

考慮到公司後期可能會出現分庫的情況,所以準備改動一下表資料,把主鍵ID改為使用雪花ID。關於雪花ID這裡不多解讀

為了方便,這邊做了攔截,所有插入操作且標記了自定義註解的欄位,均使用雪花ID生成主鍵

攔截器的程式碼比較多,這裡就不貼出來了。主要記錄一個問題,因為使用的是tk.mybatis。
通常批量插入時,使用通用mapper的insertList方法,也就是包tk.mybatis.mapper.common.special下的

@RegisterMapper
public interface InsertListMapper<T> {
    @Options
( useGeneratedKeys = true ) @InsertProvider( type = SpecialProvider.class, method = "dynamicSQL" ) int insertList(List<? extends T> var1); }

問題出在攔截器生成的雪花ID無效,因為在SpecialProvider當中,
在這裡插入圖片描述
拼接sql時跳過了主鍵。
所以需要自定義一個Provider,提供insertListByCustom方法

public class
CustomAddProvider extends MapperTemplate { public CustomAddProvider (Class<?> mapperClass, MapperHelper mapperHelper) { super(mapperClass, mapperHelper); } /** * @Title: insertListByCustom * @Description:批量新增方法 */ public String insertListByCustom(MappedStatement ms){ Class<?>
entityClass = getEntityClass(ms); //開始拼sql StringBuilder sql = new StringBuilder(); sql.append("<bind name=\"listNotEmptyCheck\" value=\"@[email protected](list, '" + ms.getId() + " 方法引數為空')\"/>"); sql.append(SqlHelper.insertIntoTable(entityClass, tableName(entityClass), "list[0]")); sql.append("<foreach collection=\"list\" item=\"record\" separator=\",\" index=\"index\">"); sql.append("<if test=\"index == 0\">"); sql.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">"); //獲取全部列 Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass); for (EntityColumn column : columnList) { if (column.isInsertable()) { sql.append(SqlHelper.getIfNotNull("record", column, column.getColumn()+",", isNotEmpty())); } } sql.append("</trim>"); sql.append("</if>"); sql.append("</foreach>"); sql.append(" VALUES "); sql.append("<foreach collection=\"list\" item=\"record\" separator=\",\" >"); sql.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">"); for (EntityColumn column : columnList) { if (column.isInsertable()) { sql.append(SqlHelper.getIfNotNull("record", column, column.getColumnHolder("record")+",", isNotEmpty())); } } sql.append("</trim>"); sql.append("</foreach>"); return sql.toString(); } }

使用時和InsertListMapper一樣,自定義一個:

@RegisterMapper
public interface CustomBatchAddMapper<T> {

	/**
	 * @Title: insertListByCustom
	 * @Description:批量插入方法
	 */
	@Options(keyProperty = "id")
	@InsertProvider(type = CustomAddProvider.class, method = "insertListByCustom")
	int insertListByCustom(List<T> recordList);

}

注意,這裡的@Options不能使用
@Options( useGeneratedKeys = true )
而是:@Options(keyProperty = "id")

否則會出現插入成功後回顯ID時不正確,會出現雪花Id自增。例如,我批量插入5條資料,假設攔截器生成的主鍵ID是(假設):0001,0002,0003,0004,0005,那麼正確的返回結果應該也是這樣。
但是實際上會返回0005,0006,0007,0008,0009.

@Options( useGeneratedKeys = true ) 改成:@Options(keyProperty = "id")即可。