系統升級後,原來的資料庫結構及業務邏輯發生了變化,升級後的系統需要兼容歷史數據,此時就需要對歷史數據進行清洗。歷史數據的清洗方式可以分為兩種:
通常,產品化的應用系統在做升級處理時,都是選擇SQL腳本的方式進行清洗數據的。
企業內部,對於線上運行的項目,使用SQL腳本對數據進行變更都需要經過工單系統,流程相對複雜。此時將清洗邏輯直接使用編碼的方式在系統中實現是相對比較簡單的。
在使用MyBatis做數據清洗時,遇到了一個問題,那就是清洗後的數據無法指定主鍵即id的值,新寫入的數據主鍵值被數據自增ID替換掉了。
/** * 自增主鍵 */@TableId(value = "id", type = IdType.AUTO)private Long id;
問題就出現在@TableId註解上。
@TableId是MyBatis-Plus提供的註解,@TableId註解代碼如下:
@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public@interface TableId { /** * <p> * 欄位值(駝峰命名方式,該值可無) * </p> */ String value() default ""; /** * <p> * 主鍵ID * </p> * {@link IdType} */ IdType type() default IdType.NONE;}
可以看到IdType是用來表示主鍵的創建方式的。
publicenum IdType { AUTO(0, "資料庫ID自增"), INPUT(1, "用戶輸入ID"), /* 以下2種類型、只有當插入對象ID 為空,才自動填充。*/ ID_WORKER(2, "全局唯一ID"), UUID(3, "全局唯一ID"), NONE(4, "該類型為未設置主鍵類型"), ID_WORKER_STR(5, "字符串全局唯一ID"); ...}
在IdType中定義了多種id生成方式。可以看AUTO的創建方式是使用資料庫ID自增,此時在執行插入操作時,MyBatis-Plus會對實體模型中的id欄位清除掉,再執行插入。
INPUT方式在實行插入時候,不會對ID主鍵進行處理,如果用戶設置了ID,將會把該值直接插入。
所以在使用編碼方式對數據進行清洗時,還需要修改模型的ID上的@TableId為@TableId(value = "id", type = IdType.AUTO)
不同的洗數方案,都有各自的優勢,在選擇方案時,還需要結合外部的環境進行全面考慮。