最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis-Plus主鍵生成策略的實(shí)現(xiàn)方法

 更新時(shí)間:2024年12月19日 09:29:18   作者:來(lái)一杯龍舌蘭  
MyBatis-Plus提供了多種主鍵生成策略,包括自增、UUID、Redis和雪花算法,本文就來(lái)介紹一下,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

什么是主鍵生成策略

通過(guò)以下代碼我們可以很直觀的看出,當(dāng)我們程序并沒(méi)有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();
}

方式二:通過(guò) 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)增長(zhǎng)策略(AUTO)

    /**
     * 數(shù)據(jù)庫(kù)ID自增
     */
    AUTO(0),

最常見(jiàn)的方式:利用數(shù)據(jù)庫(kù),全數(shù)據(jù)庫(kù)唯一。

優(yōu)點(diǎn)

1)簡(jiǎn)單,代碼方便,性能可以接受。

2)數(shù)字ID天然排序,對(duì)分頁(yè)或者需要排序的結(jié)果很有幫助。

缺點(diǎn)

1)不同數(shù)據(jù)庫(kù)語(yǔ)法和實(shí)現(xiàn)不同,數(shù)據(jù)庫(kù)遷移的時(shí)候或多數(shù)據(jù)庫(kù)版本支持的時(shí)候需要處理。

2)在單個(gè)數(shù)據(jù)庫(kù)或讀寫分離或一主多從的情況下,只有一個(gè)主庫(kù)可以生成。有單點(diǎn)故障的風(fēng)險(xiǎn)。

3)在性能達(dá)不到要求的情況下,比較難于擴(kuò)展。(不適用于海量高并發(fā))

4)如果遇見(jiàn)多個(gè)系統(tǒng)需要合并或者涉及到數(shù)據(jù)遷移會(huì)相當(dāng)痛苦。

5)分表分庫(kù)的時(shí)候會(huì)有麻煩。

6)并非一定連續(xù),類似MySQL,當(dāng)生成新ID的事務(wù)回滾,那么后續(xù)的事務(wù)也不會(huì)再用這個(gè)ID了。這個(gè)在性能和連續(xù)性的折中。如果為了保證連續(xù),必須要在事務(wù)結(jié)束后才能生成ID,那性能就會(huì)出現(xiàn)問(wèn)題。

7)在分布式數(shù)據(jù)庫(kù)中,如果采用了自增主鍵的話,有可能會(huì)帶來(lái)尾部熱點(diǎn)。分布式數(shù)據(jù)庫(kù)常常使用range的分區(qū)方式,在大量新增記錄的時(shí)候,IO會(huì)集中在一個(gè)分區(qū)上,造成熱點(diǎn)數(shù)據(jù)。

優(yōu)化方案

1)針對(duì)主庫(kù)單點(diǎn),如果有多個(gè)Master庫(kù),則每個(gè)Master庫(kù)設(shè)置的起始數(shù)字不一樣,步長(zhǎng)一樣,可以是Master的個(gè)數(shù)。比如:Master1生成的是 1,4,7,10,Master2生成的是2,5,8,11 Master3生成的是
3,6,9,12。這樣就可以有效生成集群中的唯一ID,也可以大大降低ID生成數(shù)據(jù)庫(kù)操作的負(fù)載。

全局唯一ID (UUID)

    /**
     * 全局唯一ID (UUID)
     */
    UUID(4),

常見(jiàn)的方式:可以利用數(shù)據(jù)庫(kù)也可以利用程序生成,一般來(lái)說(shuō)全球唯一。UUID是由32個(gè)的16進(jìn)制數(shù)字組成,所以每個(gè)UUID的長(zhǎng)度是128位(16^32 = 2^128)。UUID作為一種廣泛使用標(biāo)準(zhǔn),有多個(gè)實(shí)現(xiàn)版本,影響它的因素包括時(shí)間、網(wǎng)卡MAC地址、自定義Namesapce等等。

優(yōu)點(diǎn)

1)簡(jiǎn)單,代碼方便。

2)生成ID性能非常好,基本不會(huì)有性能問(wèn)題。

3)全球唯一,在遇見(jiàn)數(shù)據(jù)遷移,系統(tǒng)數(shù)據(jù)合并,或者數(shù)據(jù)庫(kù)變更等情況下,可以從容應(yīng)對(duì)。

缺點(diǎn)

1)沒(méi)有排序,無(wú)法保證趨勢(shì)遞增。

2)UUID往往是使用字符串存儲(chǔ),查詢的效率比較低。

3)存儲(chǔ)空間比較大,如果是海量數(shù)據(jù)庫(kù),就需要考慮存儲(chǔ)量的問(wèn)題。

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無(wú)序的問(wèn)題,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

使用場(chǎng)景:當(dāng)使用數(shù)據(jù)庫(kù)來(lái)生成ID性能不夠要求的時(shí)候,我們可以嘗試使用Redis來(lái)生成ID。這主要依賴于Redis是單線程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作INCR和INCRBY來(lái)實(shí)現(xiàn)。

舉例:可以使用Redis集群來(lái)獲取更高的吞吐量。假如一個(gè)集群中有5臺(tái)Redis??梢猿跏蓟颗_(tái)Redis的值分別是1,2,3,4,5,然后步長(zhǎng)都是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ù)庫(kù),靈活方便,且性能優(yōu)于數(shù)據(jù)庫(kù)。

2)數(shù)字ID天然排序,對(duì)分頁(yè)或者需要排序的結(jié)果很有幫助。

缺點(diǎn)

1)如果系統(tǒng)中沒(méi)有Redis,還需要引入新的組件,增加系統(tǒng)復(fù)雜度。

2)需要編碼和配置的工作量比較大

MP自帶策略(Twitter的snowflake算法)

snowflake是Twitter開(kāi)源的分布式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萬(wàn)左右(2^22*1000)。

主鍵生成策略的源碼剖析(IdType類詳解)

public enum IdType {
    /**
     * 數(shù)據(jù)庫(kù)ID自增
     */
    AUTO(0),
    /**
     * 該類型為未設(shè)置主鍵類型,如須使用需要手動(dòng)設(shè)置
     */
    NONE(1),
    /**
     * 用戶輸入ID
     * 該類型可以通過(guò)自己注冊(cè)自動(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • 淺談Java為什么只能單繼承

    淺談Java為什么只能單繼承

    本文主要介紹了Java為什么只能單繼承,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 使用Java編寫一個(gè)簡(jiǎn)單的Web的監(jiān)控系統(tǒng)

    使用Java編寫一個(gè)簡(jiǎn)單的Web的監(jiān)控系統(tǒng)

    這篇文章主要介紹了使用Java編寫一個(gè)簡(jiǎn)單的Web的監(jiān)控系統(tǒng)的例子,并且將重要信息轉(zhuǎn)為XML通過(guò)網(wǎng)頁(yè)前端顯示,非常之實(shí)用,需要的朋友可以參考下
    2015-11-11
  • Java行為型設(shè)計(jì)模式之模板方法詳解

    Java行為型設(shè)計(jì)模式之模板方法詳解

    模板方法的概念:定義了一個(gè)操作中的算法的骨架,而將部分步驟的實(shí)現(xiàn)在子類中完成。模板方法模式使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟
    2022-09-09
  • Java字符串定義及常用方法

    Java字符串定義及常用方法

    這篇文章主要介紹了Java字符串定義及常用方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • 輕松掌握J(rèn)ava建造者模式

    輕松掌握J(rèn)ava建造者模式

    這篇文章主要幫助大家輕松掌握J(rèn)ava建造者模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • java后端如何實(shí)現(xiàn)防止接口重復(fù)提交

    java后端如何實(shí)現(xiàn)防止接口重復(fù)提交

    這篇文章主要介紹了java后端如何實(shí)現(xiàn)防止接口重復(fù)提交問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 如何為?Spring?Boot?項(xiàng)目配置?Logback?日志

    如何為?Spring?Boot?項(xiàng)目配置?Logback?日志

    由于?Spring?Boot?的默認(rèn)日志框架選用的?Logback,再加上?Log4j2?之前爆過(guò)嚴(yán)重的漏洞,所以我們這次就只關(guān)注?Logback,本文重點(diǎn)給大家介紹如何為?Spring?Boot?項(xiàng)目配置?Logback?日志,感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • 一文詳解Java線程安全的集合有哪些

    一文詳解Java線程安全的集合有哪些

    在Java中線程安全的集合類對(duì)于多線程編程至關(guān)重要,它們能夠確保在多個(gè)線程同時(shí)訪問(wèn)集合時(shí)數(shù)據(jù)的一致性和完整性,下面這篇文章主要介紹了Java線程安全集合有哪些的相關(guān)資料,需要的朋友可以參考下
    2025-06-06
  • Java中支持可變參數(shù)詳解

    Java中支持可變參數(shù)詳解

    那個(gè)可變參數(shù)的就是個(gè)數(shù)組,你傳多少個(gè)參數(shù)都被放到那個(gè)數(shù)組里面。這樣方便了程序員,因?yàn)槿绻淮_定要傳的參數(shù)的個(gè)數(shù)的話,我們要寫帶1個(gè)參數(shù)的,帶2個(gè)參數(shù),帶3個(gè)參數(shù)的,這樣很麻煩。 該進(jìn)后的這個(gè)方法,我們只要寫一個(gè)函數(shù)就好,可以傳任意個(gè)參數(shù)。
    2015-05-05
  • kotlin之閉包案例詳解

    kotlin之閉包案例詳解

    這篇文章主要介紹了kotlin之閉包案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09

最新評(píng)論

时尚| 威信县| 曲周县| 来宾市| 枞阳县| 辽中县| 湄潭县| 贺兰县| 乌什县| 武清区| 称多县| 泽普县| 纳雍县| 芮城县| 新郑市| 扬中市| 霸州市| 容城县| 疏附县| 临西县| 云浮市| 沙田区| 阿鲁科尔沁旗| 绥中县| 台南县| 建昌县| 乳山市| 甘孜县| 高陵县| 水富县| 内丘县| 朝阳区| 年辖:市辖区| 密山市| 海宁市| 临夏市| 杭锦后旗| 德庆县| 万载县| 元氏县| 建德市|