MyBatis-Plus 主鍵生成策略的幾種實(shí)現(xiàn)方式
前言
很多人在使用Mybatis-Plus的時(shí)候可能會(huì)疑惑,自己明明沒有配置主鍵的生成策略,但是執(zhí)行新增操作時(shí)卻自動(dòng)生成了主鍵,而且還特別長(zhǎng)。這是由于Mybatis-Plus默認(rèn)就會(huì)采用雪花算法填充主鍵字段。
今天就和大家詳解聊聊Mybatis-Plus中主鍵生成的相關(guān)策略。
一、官網(wǎng)
TIP??:
推薦學(xué)習(xí)框架的時(shí)候,多研究下官網(wǎng),獲取第一手資料。
二、主鍵注解@TableId說(shuō)明
1、源碼
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) public @interface TableId { String value() default ""; IdType type() default IdType.NONE; }
屬性 | 類型 | 必須指定 | 默認(rèn)值 | 描述 |
---|---|---|---|---|
value | String | 否 | “” | 主鍵字段名 |
type | Enum | 否 | IdType.NONE | 生成主鍵類型 |
2、作用
- 標(biāo)識(shí)主鍵字段
使用@TableId可以標(biāo)識(shí)實(shí)體對(duì)象中和數(shù)據(jù)庫(kù)表中主鍵對(duì)應(yīng)的字段。如果不添加@TableId注解,會(huì)默認(rèn)匹配id字段為主鍵。 - 變量名稱和主鍵字段名稱的匹配
如果表中的主鍵字段名稱和實(shí)體中的主鍵字段名稱不相同,這時(shí)候就要通過(guò)@TableId中的value屬性明確指出對(duì)應(yīng)的數(shù)據(jù)庫(kù)主鍵字段的名稱。 - 指定主鍵的生成方式
可以通過(guò)@TableId注解中的type屬性指定主鍵的生成策略,具體支持哪些策略可以在IdType枚舉中查看。
3、使用
@TableName(value ="user") @Data public class User implements Serializable { /** * 主鍵ID */ @TableId(value = "id",type = IdType.ASSIGN_ID) private Long userId; private String name; private Integer age; private String email;
三、主鍵生成策略-IdType枚舉說(shuō)明
通過(guò)查看IdType枚舉類的源碼,可以發(fā)現(xiàn)Mybatis-Plus中默認(rèn)支持5種主鍵生成方式。
1、源碼
public enum IdType { AUTO(0), NONE(1), INPUT(2), ASSIGN_ID(3), ASSIGN_UUID(4); private final int key; private IdType(int key) { this.key = key; } public int getKey() { return this.key; } }
2、說(shuō)明
值 | 描述 |
---|---|
AUTO | 數(shù)據(jù)庫(kù) ID自增,這種情況下將表中主鍵設(shè)置為自增,否則,沒有設(shè)置主動(dòng)設(shè)置id值進(jìn)行插入時(shí)會(huì)報(bào)錯(cuò) |
NONE | 無(wú)狀態(tài),該類型為未設(shè)置主鍵類型(注解里等于跟隨全局,全局里默認(rèn) ASSIGN_ID),注意這里官網(wǎng)文檔有誤 |
INPUT | insert 前自行 set 主鍵值,在采用IKeyGenerator類型的ID生成器時(shí)必須為INPUT |
ASSIGN_ID | 分配 ID(主鍵類型為 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默認(rèn)實(shí)現(xiàn)類為DefaultIdentifierGenerator雪花算法) |
ASSIGN_UUID | 分配 UUID,主鍵類型為 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默認(rèn) default 方法) |
3、全局設(shè)置
IdType默認(rèn)的全局設(shè)置為IdType.ASSIGN_ID,即由mybatis-plus主動(dòng)分配主鍵,默認(rèn)情況下由默認(rèn)主鍵生成器實(shí)現(xiàn)類DefaultIdentifierGenerator采用雪花算法填充主鍵。
public DbConfig() { this.idType = IdType.ASSIGN_ID; this.tableUnderline = true; this.capitalMode = false; this.logicDeleteValue = "1"; this.logicNotDeleteValue = "0"; this.insertStrategy = FieldStrategy.NOT_NULL; this.updateStrategy = FieldStrategy.NOT_NULL; this.whereStrategy = FieldStrategy.NOT_NULL; }
在spring boot中,可以通過(guò)如下配置更改全局配置。
mybatis-plus.global-config.db-config.id-type=assign_id
三、ID生成器介紹
Mybatis-Plus中的ID生成器主要分為2類,一類是 IdentifierGenerator,另一類是 IKeyGenerator。
1、IdentifierGenerator
源碼如下:
public interface IdentifierGenerator { //根據(jù)id是否為null判斷是否需要主動(dòng)分配Id default boolean assignId(Object idValue) { return StringUtils.checkValNull(idValue); } //生成數(shù)值型Id Number nextId(Object entity); //生成字符型uuid default String nextUUID(Object entity) { return IdWorker.get32UUID(); } }
說(shuō)明:
IdentifierGenerator生成器中主要提供了3個(gè)方法。
其使用場(chǎng)景是:不依賴數(shù)據(jù)庫(kù)生成ID,而是由mybatis-plus自己提供一套id生成算法。 對(duì)應(yīng)的主鍵生成方式為IdType.ASSIGN_ID、ASSIGN_UUID。
- assignId 是否需要分配id
- nextId 獲取下一個(gè)數(shù)值型Id
- nextUUID 獲取下一個(gè)uuid
典型的實(shí)現(xiàn)是默認(rèn)的id生成器DefaultIdentifierGenerator,基于雪花算法生成id。
public class DefaultIdentifierGenerator implements IdentifierGenerator { private final Sequence sequence; public DefaultIdentifierGenerator() { this.sequence = new Sequence((InetAddress)null); } public DefaultIdentifierGenerator(InetAddress inetAddress) { this.sequence = new Sequence(inetAddress); } public DefaultIdentifierGenerator(long workerId, long dataCenterId) { this.sequence = new Sequence(workerId, dataCenterId); } public DefaultIdentifierGenerator(Sequence sequence) { this.sequence = sequence; } public Long nextId(Object entity) { return this.sequence.nextId(); } }
具體使用:
1、聲明由mybatis-plus分配主鍵值
@TableName(value ="user") @Data public class User implements Serializable { /** * 主鍵ID */ @TableId(value = "id",type = IdType.ASSIGN_ID) private Long userId; private String name; private Integer age; private String email;
2、指定idGenerator的實(shí)現(xiàn)類
如果是默認(rèn)的DefaultIdentifierGenerator,則不需要用戶重新指定。
@Configuration public class IdAutoConfig { @Value("${mybatis-plus.zookeeper.serverLists}") private String zkServerLists; @Bean public IdentifierGenerator idGenerator() { return new ImadcnIdentifierGenerator(zkServerLists); } }
2、IKeyGenerator
源碼如下:
public interface IKeyGenerator { //執(zhí)行sql生成id String executeSql(String incrementerName); //獲取數(shù)據(jù)庫(kù)類型 DbType dbType(); }
說(shuō)明:IKeyGenerator
生成器主要是根據(jù)不同的數(shù)據(jù)庫(kù)類型,執(zhí)行sql語(yǔ)句生成對(duì)應(yīng)的主鍵
。典型的數(shù)據(jù)庫(kù)如Oracle,Postgre,需要根據(jù)序列器生成表主鍵。
OracleKeyGenerator中的實(shí)現(xiàn):
可以發(fā)現(xiàn),是通過(guò)執(zhí)行sql調(diào)用序列器生成的id。
public class OracleKeyGenerator implements IKeyGenerator { public OracleKeyGenerator() { } public String executeSql(String incrementerName) { return "SELECT " + incrementerName + ".NEXTVAL FROM DUAL"; } public DbType dbType() { return DbType.ORACLE; } }
具體使用:
1、在實(shí)體中通過(guò)@KeySequence指定序列器名稱,并通過(guò)@TableId指定主鍵生成策略為IdType.INPUT
@KeySequence(value = "SEQ_ORACLE_STRING_KEY", clazz = String.class) public class YourEntity { @TableId(value = "ID_STR", type = IdType.INPUT) private String idStr; }
2、spring boot配置列中配置keyGenerator具體實(shí)現(xiàn)類
@Bean public IKeyGenerator keyGenerator() { return new OracleKeyGenerator(); }
也可以通過(guò)配置項(xiàng)指定:
mybatis-plus.global-config.db-config.key-generators=com.baomidou.mybatisplus.extension.incrementer.OracleKeyGenerator
四、自定義主鍵生成器
自定義主鍵生成器也有2種方式。
如果需要通過(guò)執(zhí)行sql語(yǔ)句來(lái)生成id的,可以通過(guò)實(shí)現(xiàn)IKeyGenerator接口來(lái)自定義。 如果不想依賴數(shù)據(jù)庫(kù),完全自定義一套主鍵生成策略,那么可以通過(guò)實(shí)現(xiàn)IdentifierGenerator接口來(lái)擴(kuò)展。
下面演示如何通過(guò)實(shí)現(xiàn)IdentifierGenerator接口,自定義主鍵生成器。
1、自定義id生成器
@Component public class CustomIdGenerator implements IdentifierGenerator { @Override public Long nextId(Object entity) { //可以將當(dāng)前傳入的class全類名來(lái)作為bizKey,或者提取參數(shù)來(lái)生成bizKey進(jìn)行分布式Id調(diào)用生成. String bizKey = entity.getClass().getName(); //根據(jù)bizKey調(diào)用分布式ID生成 long id = ....; //返回生成的id值即可. return id; } }
2、配置類中指定id生成器
@Bean public IdentifierGenerator idGenerator() { return new CustomIdGenerator(); }
3、實(shí)體類中指定主鍵分配策略IdType.ASSIGN_ID
@TableName(value ="user") @Data public class User implements Serializable { /** * 主鍵ID */ @TableId(value = "id",type = IdType.ASSIGN_ID) private Long userId; private String name; private Integer age; private String email;
總結(jié)
本文主要是介紹了Mybatis-Plus主鍵生成策略及其相關(guān)的擴(kuò)展方法。
1、詳細(xì)介紹了@TableId注解的屬性和作用,推薦項(xiàng)目中在實(shí)體的主鍵字段上明確添加@TableId注解,標(biāo)識(shí)id字段以及id生成策略IdType。
2、目前mybatis-plus中有5種Id生成策略IdType,搞清楚各種的用法和使用場(chǎng)景。
- AUTO 數(shù)據(jù)庫(kù) ID自增
- NONE 未設(shè)置主鍵類型,也就是跟隨全局策略,全局策略默認(rèn)為ASSIGN_ID
- INPUT insert 前自行 set 主鍵值
- ASSIGN_ID 分配 ID
- ASSIGN_UUID 分配 UUID
3、Mybatis-Plus中的ID生成器主要分為2類,一類是IdentifierGenerator,另一類是IKeyGenerator,搞清楚他們的區(qū)別和各自的使用場(chǎng)景。
- IdentifierGenerator 適用于不依賴數(shù)據(jù)庫(kù),用戶自定義的主鍵生成場(chǎng)景。
- IKeyGenerator 依賴數(shù)據(jù)庫(kù),通過(guò)執(zhí)行sql語(yǔ)句生成主鍵的場(chǎng)景。
到此這篇關(guān)于MyBatis-Plus 主鍵生成策略的幾種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)MyBatis-Plus 主鍵生成策略內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
圖解Java經(jīng)典算法冒泡排序的原理與實(shí)現(xiàn)
冒泡排序是一種簡(jiǎn)單的排序算法,它也是一種穩(wěn)定排序算法。其實(shí)現(xiàn)原理是重復(fù)掃描待排序序列,并比較每一對(duì)相鄰的元素,當(dāng)該對(duì)元素順序不正確時(shí)進(jìn)行交換。一直重復(fù)這個(gè)過(guò)程,直到?jīng)]有任何兩個(gè)相鄰元素可以交換,就表明完成了排序2022-09-09MybatisPlus保存、讀取MySQL中的json字段失敗問(wèn)題及解決
這篇文章主要介紹了MybatisPlus保存、讀取MySQL中的json字段失敗問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07Java實(shí)現(xiàn)文件名倒序排序的技術(shù)指南
在實(shí)際開發(fā)過(guò)程中,我們經(jīng)常需要對(duì)文件進(jìn)行操作和處理,一個(gè)常見的需求是按文件名倒序排列文件列表,以便于文件的管理和查找,本文將介紹如何在Java中實(shí)現(xiàn)文件名倒序排序,并提供詳細(xì)的代碼案例,需要的朋友可以參考下2024-08-08解析Spring Mvc Long類型精度丟失問(wèn)題
在平時(shí)開發(fā)過(guò)程中,經(jīng)常會(huì)使用long類型作為id的類型,但是在使用過(guò)程中會(huì)導(dǎo)致long類型數(shù)據(jù)轉(zhuǎn)換為number類型時(shí)的后兩位變?yōu)?,今天小編給大家分享Spring Mvc Long類型精度丟失問(wèn)題,需要的朋友參考下吧2021-06-06

基于Jenkins+Maven+Gitea+Nexus搭建CICD環(huán)境的方式

基于CopyOnWriteArrayList并發(fā)容器(實(shí)例講解)

Java實(shí)現(xiàn)發(fā)送短信驗(yàn)證碼功能