原文地址: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生成業務場景。
作者:文景大大
鏈接:https://www.jianshu.com/p/a59ea9bc8132
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。