MyBatis-Plus主鍵ID生成策略


原文地址:https://www.jianshu.com/p/a59ea9bc8132

MyBatis-Plus默認實現5種主鍵生成策略,分別是:

  • AUTO,配合數據庫設置自增主鍵,可以實現主鍵的自動增長,類型為nmber;
  • INPUT,由用戶輸入;
  • NONE,不設置,等同於INPUT;
  • ASSIGN_ID,只有當用戶未輸入時,采用雪花算法生成一個適用於分布式環境的全局唯一主鍵,類型可以是String和number;
  • ASSIGN_UUID,只有當用戶未輸入時,生成一個String類型的主鍵,但不保證全局唯一;

1.1 自增主鍵

我們新建一個表zx_course,建表語句如下:

CREATE TABLE `zx_course` ( `course_id` bigint(20) NOT NULL AUTO_INCREMENT, `course_name` varchar(100) NOT NULL, PRIMARY KEY (`course_id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 

其中主鍵必須設置自增,否則如下程序插入數據時就會報錯。

然后創建實體類,並標注主鍵的生成策略為AUTO:

@Data @TableName("zx_course") public class Course { @TableId(type = IdType.AUTO) private Long courseId; private String courseName; } 

基本配置就完成了,其余controller和mapper代碼如下:

@RestController public class CourseController { @Autowired private CourseMapper courseMapper; // 新增操作 @PostMapping("/addCourse") public Integer addCourse(@RequestBody Course course){ return courseMapper.insert(course); } } 
public interface CourseMapper extends BaseMapper<Course> { } 

這樣就可以正常啟動項目了。我們發起請求,不斷/addCourse,請求參數中不指定courseId,只指定courseName,會發現插入數據庫的數據主鍵是從1開始自增的。

如果此時我們指定courseId,是不會生效的。

1.2 用戶輸入

用戶輸入只要更改實體類的主鍵配置如下,數據庫表主鍵的自增是否刪除都不影響。

@TableId(type = IdType.INPUT) private Long courseId; 

此時我們調用/addCourse,請求參數中同時帶上courseId和courseName,就能插入我們自己輸入的主鍵了。

如果此時請求沒有帶上courseId,那么自增特性自動生效。

1.3 未指定

同INPUT的效果。

1.4 雪花算法生成ID

@TableId(type = IdType.ASSIGN_ID) private Long courseId; 

以上設置只有在用戶沒有輸入courseId時,才會采用雪花算法生成一個主鍵,如果用戶有輸入,還是以用戶輸入的為准。當實體類中主鍵聲明的是Long數值或者String類型時(不可以是Integer,否則報錯),就會生成19位純數字的主鍵;

1.5 UUID

@TableId(type = IdType.ASSIGN_UUID) private String courseId; 

以上設置只有在用戶沒有輸入courseId時,才會生成一個32位的數字+字母組合的主鍵值,要求實體類中的類型必須是String,而且數據庫對應的字段為varchar(32);

1.6 Sequence

對於INPUT類型,一種情況是程序里面自己指定主鍵,還有一種是利用MyBatis-Plus自帶的如下主鍵生成器生成:

  • DB2KeyGenerator
  • H2KeyGenerator
  • KingbaseKeyGenerator
  • OracleKeyGenerator
  • PostgreKeyGenerator

這些KeyGenerator都是實現IKeyGenerator接口,如果不能滿足你,可以自己新建一個KeyGenerator,然后實現IKeyGenerator即可。

如何使用這些KeyGenerator呢?很簡單,兩個步驟即可。

在配置類中加上想要使用哪個KeyGenerator:

@Bean public IKeyGenerator keyGenerator() { // 選擇你要使用的KeyGenerator return new OracleKeyGenerator(); } 

然后在實體類上聲明@KeySequence,指定使用的Sequence名稱,並指定主鍵類型為INPUT。

@Data @TableName("zx_course") @KeySequence(value = "my_oracle_sequence") public class Course { @TableId(type = IdType.INPUT) private String courseId; private String courseName; } 

以上要求數據庫中已經存在my_oracle_sequence這個序列,在使用時,會調用SELECT my_oracle_sequence.NEXTVAL FROM DUAL來獲取一個序列填充到主鍵中。而且如果你是MySQL,就沒有默認支持的KeyGenerator可以使用。

因此個人感覺不是很好用,還是UUID和雪花算法比較簡單實用。

1.7 自定義ID生成器

在前面我們已經介紹了ASSIGN_ID,其默認是采用雪花算法實現的,我們可以自定義一個ID生成器。

@TableId(type = IdType.ASSIGN_ID) private String courseId; 
@Slf4j @Component public class CustomIdGenerator implements IdentifierGenerator { private final AtomicLong al = new AtomicLong(1); @Override public Long nextId(Object entity) { //可以將當前傳入的class全類名來作為bizKey,或者提取參數來生成bizKey進行分布式Id調用生成. String bizKey = entity.getClass().getName(); log.info("bizKey:{}", bizKey); MetaObject metaObject = SystemMetaObject.forObject(entity); String name = (String) metaObject.getValue("courseName"); final long id = al.getAndAdd(1); log.info("為{}生成主鍵值->:{}", name, id); return id + 10000; } } 

如上配置內容就是覆蓋默認的雪花算法,自己實現一個ID生成邏輯,滿足特殊的ID生成業務場景。

 
 
2人點贊
 
 


作者:文景大大
鏈接:https://www.jianshu.com/p/a59ea9bc8132
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

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



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