MyBatis-Plus主鍵生成策略的實現(xiàn)方法
什么是主鍵生成策略
通過以下代碼我們可以很直觀的看出,當(dāng)我們程序并沒有set主鍵的時候,MyBatis-Plus是自動幫我們set了一個19位的id主鍵,這就體現(xiàn)了MyBatis-Plus的主鍵生成策略
附git地址:https://gitee.com/its-a-little-bad/mybatisplus—chapter-1.git

主鍵生成策略的配置方式
Spring-Boot
方式一:使用配置類
@Bean
public IKeyGenerator keyGenerator() {
return new H2KeyGenerator();
}
方式二:通過 MybatisPlusPropertiesCustomizer 自定義
@Bean
public MybatisPlusPropertiesCustomizer plusPropertiesCustomizer() {
return plusProperties -> plusProperties.getGlobalConfig().getDbConfig().setKeyGenerator(new H2KeyGenerator());
}
Spring
方式一: XML 配置
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig"> <property name="dbConfig" ref="dbConfig"/> </bean> <bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig"> <property name="keyGenerator" ref="keyGenerator"/> </bean> <bean id="keyGenerator" class="com.baomidou.mybatisplus.extension.incrementer.H2KeyGenerator"/>
方式二:注解配置
@Bean
public GlobalConfig globalConfig() {
GlobalConfig conf = new GlobalConfig();
conf.setDbConfig(new GlobalConfig.DbConfig().setKeyGenerator(new H2KeyGenerator()));
return conf;
}
主鍵生成策略的實現(xiàn)方式
自動增長策略(AUTO)
/**
* 數(shù)據(jù)庫ID自增
*/
AUTO(0),
最常見的方式:利用數(shù)據(jù)庫,全數(shù)據(jù)庫唯一。
優(yōu)點:
1)簡單,代碼方便,性能可以接受。
2)數(shù)字ID天然排序,對分頁或者需要排序的結(jié)果很有幫助。
缺點:
1)不同數(shù)據(jù)庫語法和實現(xiàn)不同,數(shù)據(jù)庫遷移的時候或多數(shù)據(jù)庫版本支持的時候需要處理。
2)在單個數(shù)據(jù)庫或讀寫分離或一主多從的情況下,只有一個主庫可以生成。有單點故障的風(fēng)險。
3)在性能達(dá)不到要求的情況下,比較難于擴展。(不適用于海量高并發(fā))
4)如果遇見多個系統(tǒng)需要合并或者涉及到數(shù)據(jù)遷移會相當(dāng)痛苦。
5)分表分庫的時候會有麻煩。
6)并非一定連續(xù),類似MySQL,當(dāng)生成新ID的事務(wù)回滾,那么后續(xù)的事務(wù)也不會再用這個ID了。這個在性能和連續(xù)性的折中。如果為了保證連續(xù),必須要在事務(wù)結(jié)束后才能生成ID,那性能就會出現(xiàn)問題。
7)在分布式數(shù)據(jù)庫中,如果采用了自增主鍵的話,有可能會帶來尾部熱點。分布式數(shù)據(jù)庫常常使用range的分區(qū)方式,在大量新增記錄的時候,IO會集中在一個分區(qū)上,造成熱點數(shù)據(jù)。
優(yōu)化方案:
1)針對主庫單點,如果有多個Master庫,則每個Master庫設(shè)置的起始數(shù)字不一樣,步長一樣,可以是Master的個數(shù)。比如:Master1生成的是 1,4,7,10,Master2生成的是2,5,8,11 Master3生成的是
3,6,9,12。這樣就可以有效生成集群中的唯一ID,也可以大大降低ID生成數(shù)據(jù)庫操作的負(fù)載。
全局唯一ID (UUID)
/**
* 全局唯一ID (UUID)
*/
UUID(4),
常見的方式:可以利用數(shù)據(jù)庫也可以利用程序生成,一般來說全球唯一。UUID是由32個的16進制數(shù)字組成,所以每個UUID的長度是128位(16^32 = 2^128)。UUID作為一種廣泛使用標(biāo)準(zhǔn),有多個實現(xiàn)版本,影響它的因素包括時間、網(wǎng)卡MAC地址、自定義Namesapce等等。
優(yōu)點:
1)簡單,代碼方便。
2)生成ID性能非常好,基本不會有性能問題。
3)全球唯一,在遇見數(shù)據(jù)遷移,系統(tǒng)數(shù)據(jù)合并,或者數(shù)據(jù)庫變更等情況下,可以從容應(yīng)對。
缺點:
1)沒有排序,無法保證趨勢遞增。
2)UUID往往是使用字符串存儲,查詢的效率比較低。
3)存儲空間比較大,如果是海量數(shù)據(jù)庫,就需要考慮存儲量的問題。
4)傳輸數(shù)據(jù)量大
5)不可讀。
深入UUID的變種(了解即可)
//為了解決UUID不可讀,可以使用UUID to Int64的方法
public static long GuidToInt64()
{
byte[] bytes = Guid.NewGuid().ToByteArray();
return BitConverter.ToInt64(bytes, 0);
}
//為了解決UUID無序的問題,NHibernate在其主鍵生成方式中提供了Comb算法(combined guid/timestamp)。保留GUID的10個字節(jié),用另6個字節(jié)表示GUID生成的時間(DateTime)
private Guid GenerateComb()
{
byte[] guidArray = Guid.NewGuid().ToByteArray();
DateTime baseDate = new DateTime(1900, 1, 1);
DateTime now = DateTime.Now;
TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);
TimeSpan msecs = now.TimeOfDay;
byte[] daysArray = BitConverter.GetBytes(days.Days);
byte[] msecsArray = BitConverter.GetBytes((long)
(msecs.TotalMilliseconds / 3.333333));
Array.Reverse(daysArray);
Array.Reverse(msecsArray);
Array.Copy(daysArray, daysArray.Length - 2, guidArray,
guidArray.Length - 6, 2);
Array.Copy(msecsArray, msecsArray.Length - 4, guidArray,
guidArray.Length - 4, 4);
return new Guid(guidArray);
}
Redis生成ID
使用場景:當(dāng)使用數(shù)據(jù)庫來生成ID性能不夠要求的時候,我們可以嘗試使用Redis來生成ID。這主要依賴于Redis是單線程的,所以也可以用生成全局唯一的ID??梢杂肦edis的原子操作INCR和INCRBY來實現(xiàn)。
舉例:可以使用Redis集群來獲取更高的吞吐量。假如一個集群中有5臺Redis??梢猿跏蓟颗_Redis的值分別是1,2,3,4,5,然后步長都是5。各個Redis生成的ID為:
A:1,6,11,16,21
B:2,7,12,17,22
C:3,8,13,18,23
D:4,9,14,19,24
E:5,10,15,20,25
優(yōu)點:
1)不依賴于數(shù)據(jù)庫,靈活方便,且性能優(yōu)于數(shù)據(jù)庫。
2)數(shù)字ID天然排序,對分頁或者需要排序的結(jié)果很有幫助。
缺點:
1)如果系統(tǒng)中沒有Redis,還需要引入新的組件,增加系統(tǒng)復(fù)雜度。
2)需要編碼和配置的工作量比較大
MP自帶策略(Twitter的snowflake算法)
snowflake是Twitter開源的分布式ID生成算法,結(jié)果是一個long型的ID。
核心思想:使用41bit作為毫秒數(shù),10bit作為機器的ID(5個bit是數(shù)據(jù)中心,5個bit的機器ID),12bit作為毫秒內(nèi)的流水號(意味著每個節(jié)點在每毫秒可以產(chǎn)生4096 個ID),最后還有一個符號位,永遠(yuǎn)是0。具體實現(xiàn)的代碼可以參看https://github.com/twitter/snowflake。
TPS:雪花算法支持的TPS可以達(dá)到419萬左右(2^22*1000)。
主鍵生成策略的源碼剖析(IdType類詳解)
public enum IdType {
/**
* 數(shù)據(jù)庫ID自增
*/
AUTO(0),
/**
* 該類型為未設(shè)置主鍵類型,如須使用需要手動設(shè)置
*/
NONE(1),
/**
* 用戶輸入ID
* 該類型可以通過自己注冊自動填充插件進行填充,如須使用需要手動設(shè)置
*/
INPUT(2),
/**
* 全局唯一ID (UUID)
*/
UUID(4),
//以下兩種為MP自帶策略
/**
* 全局唯一ID (idWorker),生成19位值,數(shù)字類型使用這種策略,比如long
*/
ID_WORKER(3),
/**
* 字符串全局唯一ID,生成19位值,字符串類型使用這種策略,比如String
*/
ID_WORKER_STR(5);
}到此這篇關(guān)于MyBatis-Plus主鍵生成策略的實現(xiàn)方法的文章就介紹到這了,更多相關(guān)MyBatis-Plus主鍵生成策略內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解讀@SpringBootApplication注解有什么用
@SpringBootApplication是SpringBoot的核心注解,主要包含@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三個注解,這些注解共同簡化了Spring應(yīng)用的配置工作,并使得通過主程序類就可以啟動SpringBoot應(yīng)用2024-09-09
Java自動化實現(xiàn)提取PDF表格數(shù)據(jù)
在數(shù)字化背景下,數(shù)據(jù)是企業(yè)決策的重要依據(jù),如何高效、準(zhǔn)確地將PDF中的表格數(shù)據(jù)提取出來,并轉(zhuǎn)換為可分析的結(jié)構(gòu)化格式是面臨的普遍問題,下面我們就來看看具體實現(xiàn)方法吧2025-09-09
springboot 在ftl頁面上使用shiro標(biāo)簽的實例代碼
這篇文章主要介紹了springboot 在ftl頁面上使用shiro標(biāo)簽的實例代碼,通過文字說明結(jié)合實例的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧2018-05-05
Java Web Filter 過濾器學(xué)習(xí)教程(推薦)
Filter也稱之為過濾器,它是Servlet技術(shù)中最激動人心的技術(shù).這篇文章主要介紹了Java Web Filter 過濾器學(xué)習(xí)教程的相關(guān)資料,需要的朋友可以參考下2016-05-05
Mybatis基于MapperScan注解的動態(tài)代理加載機制詳解
這篇文章主要介紹了Mybatis基于MapperScan注解的動態(tài)代理加載機制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-01-01
SpringCloud集成Micrometer Tracing的代碼工程
Micrometer Tracing 是一個用于微服務(wù)架構(gòu)的追蹤庫,它提供了一種簡單而強大的方式來收集和報告分布式系統(tǒng)中的性能和調(diào)用鏈信息,Micrometer Tracing 旨在幫助開發(fā)者和運維人員理解微服務(wù)之間的交互,本文給大家介紹了如何在 Spring Cloud 集成 Micrometer Tracing2024-12-12

