亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

什么是主鍵生成策略

通過以下代碼我們可以很直觀的看出,當(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)文章

最新評(píng)論