1. 程式人生 > 實用技巧 >記一次mybatis攔截器實現ID生成

記一次mybatis攔截器實現ID生成

1. 需求:對資料庫id統一生成

2. 實現方案:通過mybatis攔截器,攔截sql,對要插入的資料重置id

3. 上程式碼:

/**
 * @author yangxj
 * @date 2020-08-10 15:57
 * <p>
 * 自定義id生成器
 */
@Component
@Intercepts(@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}))
public class IDGeneratorPlugin implements
Interceptor { // 實體主鍵欄位 private final static String ID_FIELD = "id"; @Override @SuppressWarnings("unchecked") public Object intercept(Invocation invocation) throws Throwable { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; Object param
= invocation.getArgs()[1]; SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType(); // 非插入型別跳過 if (!sqlCommandType.equals(SqlCommandType.INSERT)) { return invocation.proceed(); } // 引數型別 map or entity // 注: mybatis在處理多引數,以及引數型別為集合時,會將引數轉map型別處理
if (param instanceof Map) { Map paramMap = (Map)param; // 是否為批量插入操作 Optional batchParam = paramMap.values().stream().filter(paramValues -> paramValues instanceof List).findFirst(); if (batchParam.isPresent()) { for (Object o : (List) batchParam.get()) { restId(o); // 設定id } } else { paramMap.put(ID_FIELD, IdUtil.fastSimpleUUID()); // 設定id } } else { restId(param); } return invocation.proceed(); } private void restId(Object param) { try { Field id = param.getClass().getDeclaredField(ID_FIELD); id.setAccessible(true); //TODO id生成邏輯自實現 if (Objects.isNull(id.get(param))) { id.set(param, IdUtil.fastSimpleUUID()); } } catch (Exception e) { } } @Override public Object plugin(Object target) { return target instanceof Executor ? (Plugin.wrap(target, this)) : target; } @Override public void setProperties(Properties properties) { } }

4. over