MyBatis-Plus主鍵生成策略的實(shí)現(xiàn)方法
什么是主鍵生成策略
通過以下代碼我們可以很直觀的看出,當(dāng)我們程序并沒有set主鍵的時(shí)候,MyBatis-Plus是自動(dòng)幫我們set了一個(gè)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; }
主鍵生成策略的實(shí)現(xiàn)方式
自動(dòng)增長策略(AUTO)
/** * 數(shù)據(jù)庫ID自增 */ AUTO(0),
最常見的方式:利用數(shù)據(jù)庫,全數(shù)據(jù)庫唯一。
優(yōu)點(diǎn):
1)簡單,代碼方便,性能可以接受。
2)數(shù)字ID天然排序,對(duì)分頁或者需要排序的結(jié)果很有幫助。
缺點(diǎn):
1)不同數(shù)據(jù)庫語法和實(shí)現(xiàn)不同,數(shù)據(jù)庫遷移的時(shí)候或多數(shù)據(jù)庫版本支持的時(shí)候需要處理。
2)在單個(gè)數(shù)據(jù)庫或讀寫分離或一主多從的情況下,只有一個(gè)主庫可以生成。有單點(diǎn)故障的風(fēng)險(xiǎn)。
3)在性能達(dá)不到要求的情況下,比較難于擴(kuò)展。(不適用于海量高并發(fā))
4)如果遇見多個(gè)系統(tǒng)需要合并或者涉及到數(shù)據(jù)遷移會(huì)相當(dāng)痛苦。
5)分表分庫的時(shí)候會(huì)有麻煩。
6)并非一定連續(xù),類似MySQL,當(dāng)生成新ID的事務(wù)回滾,那么后續(xù)的事務(wù)也不會(huì)再用這個(gè)ID了。這個(gè)在性能和連續(xù)性的折中。如果為了保證連續(xù),必須要在事務(wù)結(jié)束后才能生成ID,那性能就會(huì)出現(xiàn)問題。
7)在分布式數(shù)據(jù)庫中,如果采用了自增主鍵的話,有可能會(huì)帶來尾部熱點(diǎn)。分布式數(shù)據(jù)庫常常使用range的分區(qū)方式,在大量新增記錄的時(shí)候,IO會(huì)集中在一個(gè)分區(qū)上,造成熱點(diǎn)數(shù)據(jù)。
優(yōu)化方案:
1)針對(duì)主庫單點(diǎn),如果有多個(gè)Master庫,則每個(gè)Master庫設(shè)置的起始數(shù)字不一樣,步長一樣,可以是Master的個(gè)數(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個(gè)的16進(jìn)制數(shù)字組成,所以每個(gè)UUID的長度是128位(16^32 = 2^128)。UUID作為一種廣泛使用標(biāo)準(zhǔn),有多個(gè)實(shí)現(xiàn)版本,影響它的因素包括時(shí)間、網(wǎng)卡MAC地址、自定義Namesapce等等。
優(yōu)點(diǎn):
1)簡單,代碼方便。
2)生成ID性能非常好,基本不會(huì)有性能問題。
3)全球唯一,在遇見數(shù)據(jù)遷移,系統(tǒng)數(shù)據(jù)合并,或者數(shù)據(jù)庫變更等情況下,可以從容應(yīng)對(duì)。
缺點(diǎn):
1)沒有排序,無法保證趨勢遞增。
2)UUID往往是使用字符串存儲(chǔ),查詢的效率比較低。
3)存儲(chǔ)空間比較大,如果是海量數(shù)據(jù)庫,就需要考慮存儲(chǔ)量的問題。
4)傳輸數(shù)據(jù)量大
5)不可讀。
深入U(xiǎn)UID的變種(了解即可)
//為了解決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個(gè)字節(jié),用另6個(gè)字節(jié)表示GUID生成的時(shí)間(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性能不夠要求的時(shí)候,我們可以嘗試使用Redis來生成ID。這主要依賴于Redis是單線程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作INCR和INCRBY來實(shí)現(xiàn)。
舉例:可以使用Redis集群來獲取更高的吞吐量。假如一個(gè)集群中有5臺(tái)Redis??梢猿跏蓟颗_(tái)Redis的值分別是1,2,3,4,5,然后步長都是5。各個(gè)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)點(diǎn):
1)不依賴于數(shù)據(jù)庫,靈活方便,且性能優(yōu)于數(shù)據(jù)庫。
2)數(shù)字ID天然排序,對(duì)分頁或者需要排序的結(jié)果很有幫助。
缺點(diǎn):
1)如果系統(tǒng)中沒有Redis,還需要引入新的組件,增加系統(tǒng)復(fù)雜度。
2)需要編碼和配置的工作量比較大
MP自帶策略(Twitter的snowflake算法)
snowflake是Twitter開源的分布式ID生成算法,結(jié)果是一個(gè)long型的ID。
核心思想:使用41bit作為毫秒數(shù),10bit作為機(jī)器的ID(5個(gè)bit是數(shù)據(jù)中心,5個(gè)bit的機(jī)器ID),12bit作為毫秒內(nèi)的流水號(hào)(意味著每個(gè)節(jié)點(diǎn)在每毫秒可以產(chǎn)生4096 個(gè)ID),最后還有一個(gè)符號(hào)位,永遠(yuǎn)是0。具體實(shí)現(xiàn)的代碼可以參看https://github.com/twitter/snowflake。
TPS:雪花算法支持的TPS可以達(dá)到419萬左右(2^22*1000)。
主鍵生成策略的源碼剖析(IdType類詳解)
public enum IdType { /** * 數(shù)據(jù)庫ID自增 */ AUTO(0), /** * 該類型為未設(shè)置主鍵類型,如須使用需要手動(dòng)設(shè)置 */ NONE(1), /** * 用戶輸入ID * 該類型可以通過自己注冊自動(dòng)填充插件進(jìn)行填充,如須使用需要手動(dòng)設(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主鍵生成策略的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)MyBatis-Plus主鍵生成策略內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java數(shù)據(jù)結(jié)構(gòu)基礎(chǔ):單,雙向鏈表
這篇文章主要介紹了Java的數(shù)據(jù)解構(gòu)基礎(chǔ),希望對(duì)廣大的程序愛好者有所幫助,同時(shí)祝大家有一個(gè)好成績,需要的朋友可以參考下,希望能給你帶來幫助2021-07-07詳解MyBatis的getMapper()接口、resultMap標(biāo)簽、Alias別名、 盡量提取sql列、動(dòng)態(tài)操作
這篇文章主要介紹了詳解MyBatis的getMapper()接口、resultMap標(biāo)簽、Alias別名、 盡量提取sql列、動(dòng)態(tài)操作的相關(guān)資料,需要的朋友可以參考下2016-08-08SpringBoot整合MyBatis Plus實(shí)現(xiàn)基本CRUD與高級(jí)功能
Spring Boot是一款用于快速構(gòu)建Spring應(yīng)用程序的框架,而MyBatis Plus是MyBatis的增強(qiáng)工具,本文將詳細(xì)介紹如何在Spring Boot項(xiàng)目中整合MyBatis Plus,并展示其基本CRUD功能以及高級(jí)功能的實(shí)現(xiàn)方式,需要的朋友可以參考下2024-02-02java實(shí)現(xiàn)識(shí)別二維碼圖片功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)識(shí)別二維碼圖片功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04Java 十進(jìn)制轉(zhuǎn)二、八、十六進(jìn)制的字符串
本文主要介紹了十進(jìn)制轉(zhuǎn)二進(jìn)制;十進(jìn)制轉(zhuǎn)八進(jìn)制;十進(jìn)制轉(zhuǎn)十六進(jìn)制的方法,具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-02-02SpringBoot如何配置文件properties和yml
這篇文章主要介紹了SpringBoot如何配置文件properties和yml問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08springmvc 傳遞和接收數(shù)組參數(shù)的實(shí)例
下面小編就為大家分享一篇springmvc 傳遞和接收數(shù)組參數(shù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03