久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Hibernate各種主鍵生成策略與配置詳解

1,、assigned

主鍵由外部程序負(fù)責(zé)生成,在 save() 之前必須指定一個(gè)。Hibernate不負(fù)責(zé)維護(hù)主鍵生成,。與Hibernate和底層數(shù)據(jù)庫都無關(guān),,可以跨數(shù)據(jù)庫。在存儲(chǔ)對(duì)象前,,必須要使用主鍵的setter方法給主鍵賦值,,至于這個(gè)值怎么生成,完全由自己決定,,這種方法應(yīng)該盡量避免,。

<id name="id" column="id">

<generator class="assigned" />

</id>

ud”是自定義的策略名,人為起的名字,,后面均用“ud”表示,。

特點(diǎn):可以跨數(shù)據(jù)庫,人為控制主鍵生成,,應(yīng)盡量避免,。

2increment

Hibernate從數(shù)據(jù)庫中取出主鍵的最大值(每個(gè)session只取1次),,以該值為基礎(chǔ),,每次增量為1,在內(nèi)存中生成主鍵,,不依賴于底層的數(shù)據(jù)庫,,因此可以跨數(shù)據(jù)庫。

<id name="id" column="id">

<generator class="increment" />

</id>

Hibernate調(diào)用org.hibernate.id.IncrementGenerator類里面的generate()方法,,使用select max(idColumnName) from tableName語句獲取主鍵最大值,。該方法被聲明成了synchronized,所以在一個(gè)獨(dú)立的Java虛擬機(jī)內(nèi)部是沒有問題的,,然而,,在多個(gè)JVM同時(shí)并發(fā)訪問數(shù)據(jù)庫select max時(shí)就可能取出相同的值,再insert就會(huì)發(fā)生Dumplicate entry的錯(cuò)誤,。所以只能有一個(gè)Hibernate應(yīng)用進(jìn)程訪問數(shù)據(jù)庫,,否則就可能產(chǎn)生主鍵沖突,,所以不適合多進(jìn)程并發(fā)更新數(shù)據(jù)庫,,適合單一進(jìn)程訪問數(shù)據(jù)庫,,不能用于群集環(huán)境,。

官方文檔:只有在沒有其他進(jìn)程往同一張表中插入數(shù)據(jù)時(shí)才能使用,在集群下不要使用,。

特點(diǎn):跨數(shù)據(jù)庫,,不適合多進(jìn)程并發(fā)更新數(shù)據(jù)庫,,適合單一進(jìn)程訪問數(shù)據(jù)庫,,不能用于群集環(huán)境。

3hilo

hilo(高低位方式high low)是hibernate中最常用的一種生成方式,,需要一張額外的表保存hi的值,。保存hi值的表至少有一條記錄(只與第一條記錄有關(guān)),否則會(huì)出現(xiàn)錯(cuò)誤,。可以跨數(shù)據(jù)庫,。

<id name="id" column="id">

<generator class="hilo">

<param name="table">hibernate_hilo</param>

<param name="column">next_hi</param>

<param name="max_lo">100</param>

</generator>

</id>

<param name="table">hibernate_hilo</param> 指定保存hi值的表名

<param name="column">next_hi</param> 指定保存hi值的列名

<param name="max_lo">100</param> 指定低位的最大值

也可以省略tablecolumn配置,其默認(rèn)的表為hibernate_unique_key,,列為next_hi

<id name="id" column="id">

<generator class="hilo">

<param name="max_lo">100</param>

</generator>

</id>

hilo生成器生成主鍵的過程(以hibernate_unique_key表,,next_hi列為例):

1. 獲得hi值:讀取并記錄數(shù)據(jù)庫的hibernate_unique_key表中next_hi字段的值,數(shù)據(jù)庫中此字段值加1保存,。

2. 獲得lo值:從0max_lo循環(huán)取值,,差值為1,當(dāng)值為max_lo值時(shí),,重新獲取hi值,,然后lo值繼續(xù)從0max_lo循環(huán)。

3. 根據(jù)公式 hi * (max_lo + 1) + lo計(jì)算生成主鍵值,。

注意:當(dāng)hi值是0的時(shí)候,,那么第一個(gè)值不是0*(max_lo+1)+0=0,而是lo跳過01開始,,直接是1,、23……

max_lo配置多大合適呢,?

這要根據(jù)具體情況而定,,如果系統(tǒng)一般不重啟,而且需要用此表建立大量的主鍵,,可以吧max_lo配置大一點(diǎn),,這樣可以減少讀取數(shù)據(jù)表的次數(shù),提高效率,;反之,,如果服務(wù)器經(jīng)常重啟,可以吧max_lo配置小一點(diǎn),,可以避免每次重啟主鍵之間的間隔太大,,造成主鍵值主鍵不連貫。

特點(diǎn):跨數(shù)據(jù)庫,,hilo算法生成的標(biāo)志只能在一個(gè)數(shù)據(jù)庫中保證唯一,。

4seqhilo

hilo類似,,通過hi/lo算法實(shí)現(xiàn)的主鍵生成機(jī)制,,只是將hilo中的數(shù)據(jù)表換成了序列sequence,,需要數(shù)據(jù)庫中先創(chuàng)建sequence,適用于支持sequence的數(shù)據(jù)庫,,如oracle,。

<id name="id" column="id">

<generator class="seqhilo">

<param name="sequence">hibernate_seq</param>

<param name="max_lo">100</param>

</generator>

</id>

特點(diǎn):與hilo類似,只能在支持序列的數(shù)據(jù)庫中使用,。

5,、sequence

采用數(shù)據(jù)庫提供的sequence機(jī)制生成主鍵,需要數(shù)據(jù)庫支持sequence,。如oralce,、DBSAP DB,、PostgerSQL,、McKoi中的sequenceMySQL這種不支持sequence的數(shù)據(jù)庫則不行(可以使用identity),。

<generator class="sequence">

<param name="sequence">hibernate_id</param>

</generator>

<param name="sequence">hibernate_id</param> 指定sequence的名稱

Hibernate生成主鍵時(shí),,查找sequence并賦給主鍵值,主鍵值由數(shù)據(jù)庫生成,,Hibernate不負(fù)責(zé)維護(hù),,使用時(shí)必須先創(chuàng)建一個(gè)sequence,如果不指定sequence名稱,,則使用Hibernate默認(rèn)的sequence,,名稱為hibernate_sequence,前提要在數(shù)據(jù)庫中創(chuàng)建該sequence,。

特點(diǎn):只能在支持序列的數(shù)據(jù)庫中使用,,如Oracle

6,、identity

identity由底層數(shù)據(jù)庫生成標(biāo)識(shí)符,。identity是由數(shù)據(jù)庫自己生成的,但這個(gè)主鍵必須設(shè)置為自增長,,使用identity的前提條件是底層數(shù)據(jù)庫支持自動(dòng)增長字段類型,,如DB2SQL Server,、MySQL,、SybaseHypersonicSQL等,Oracle這類沒有自增字段的則不支持,。

<id name="id" column="id">

<generator class="identity" />

</id>

例:如果使用MySQL數(shù)據(jù)庫,,則主鍵字段必須設(shè)置成auto_increment

id int(11) primary key auto_increment

特點(diǎn):只能用在支持自動(dòng)增長的字段數(shù)據(jù)庫中使用,,如MySQL,。

7,、native

nativehibernate根據(jù)使用的數(shù)據(jù)庫自行判斷采用identityhilo,、sequence其中一種作為主鍵生成方式,,靈活性很強(qiáng),。如果能支持identity則使用identity,,如果支持sequence則使用sequence

<id name="id" column="id">

<generator class="native" />

</id>

例如MySQL使用identity,,Oracle使用sequence

注意:如果Hibernate自動(dòng)選擇sequence或者hilo,,則所有的表的主鍵都會(huì)從Hibernate默認(rèn)的sequencehilo表中取。并且,,有的數(shù)據(jù)庫對(duì)于默認(rèn)情況主鍵生成測(cè)試的支持,,效率并不是很高。

使用sequencehilo時(shí),,可以加入?yún)?shù),,指定sequence名稱或hi值表名稱等,如

<param name="sequence">hibernate_id</param>

特點(diǎn):根據(jù)數(shù)據(jù)庫自動(dòng)選擇,,項(xiàng)目中如果用到多個(gè)數(shù)據(jù)庫時(shí),,可以使用這種方式,使用時(shí)需要設(shè)置表的自增字段或建立序列,,建立表等,。

8uuid

UUIDUniversally Unique Identifier,,是指在一臺(tái)機(jī)器上生成的數(shù)字,,它保證對(duì)在同一時(shí)空中的所有機(jī)器都是唯一的。按照開放軟件基金會(huì)(OSF)制定的標(biāo)準(zhǔn)計(jì)算,,用到了以太網(wǎng)卡地址,、納秒級(jí)時(shí)間、芯片ID碼和許多可能的數(shù)字,,標(biāo)準(zhǔn)的UUID格式為:

xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx (8-4-4-4-12)

其中每個(gè) x 0-9a-f 范圍內(nèi)的一個(gè)十六進(jìn)制的數(shù)字,。

<id name="id" column="id">

<generator class="uuid" />

</id>

Hibernate在保存對(duì)象時(shí),生成一個(gè)UUID字符串作為主鍵,,保證了唯一性,,但其并無任何業(yè)務(wù)邏輯意義,只能作為主鍵,,唯一缺點(diǎn)長度較大,,32位(HibernateUUID中間的“-”刪除了)的字符串,占用存儲(chǔ)空間大,,但是有兩個(gè)很重要的優(yōu)點(diǎn),,Hibernate在維護(hù)主鍵時(shí),,不用去數(shù)據(jù)庫查詢,從而提高效率,,而且它是跨數(shù)據(jù)庫的,,以后切換數(shù)據(jù)庫極其方便。

特點(diǎn):uuid長度大,,占用空間大,,跨數(shù)據(jù)庫,不用訪問數(shù)據(jù)庫就生成主鍵值,,所以效率高且能保證唯一性,,移植非常方便,推薦使用,。

9,、guid

GUIDGlobally Unique Identifier全球唯一標(biāo)識(shí)符,也稱作 UUID,,是一個(gè)128位長的數(shù)字,,用16進(jìn)制表示。算法的核心思想是結(jié)合機(jī)器的網(wǎng)卡,、當(dāng)?shù)貢r(shí)間,、一個(gè)隨即數(shù)來生成GUID。從理論上講,,如果一臺(tái)機(jī)器每秒產(chǎn)生10000000個(gè)GUID,,則可以保證(概率意義上)3240年不重復(fù)。

<id name="id" column="id">

<generator class="guid" />

</id>

Hibernate在維護(hù)主鍵時(shí),,先查詢數(shù)據(jù)庫,,獲得一個(gè)uuid字符串,該字符串就是主鍵值,,該值唯一,,缺點(diǎn)長度較大,支持?jǐn)?shù)據(jù)庫有限,,優(yōu)點(diǎn)同uuid,,跨數(shù)據(jù)庫,但是仍然需要訪問數(shù)據(jù)庫,。

注意:長度因數(shù)據(jù)庫不同而不同

MySQL中使用select uuid()語句獲得的為36位(包含標(biāo)準(zhǔn)格式的“-”)

Oracle中,,使用select rawtohex(sys_guid()) from dual語句獲得的為32位(不包含“-”) 特點(diǎn):需要數(shù)據(jù)庫支持查詢uuid,生成時(shí)需要查詢數(shù)據(jù)庫,,效率沒有uuid高,,推薦使用uuid

10,、foreign

使用另外一個(gè)相關(guān)聯(lián)的對(duì)象的主鍵作為該對(duì)象主鍵,。主要用于一對(duì)一關(guān)系中,。

<id name="id" column="id">

<generator class="foreign">

<param name="property">user</param>

</generator>

</id>

<one-to-one name="user" class="domain.User" constrained="true" />

該例使用domain.User的主鍵作為本類映射的主鍵。

特點(diǎn):很少使用,,大多用在一對(duì)一關(guān)系中,。

11select

使用觸發(fā)器生成主鍵,,主要用于早期的數(shù)據(jù)庫主鍵生成機(jī)制,,能用到的地方非常少。

12,、其他注釋方式配置

注釋方式與配置文件底層實(shí)現(xiàn)方式相同,,只是配置的方式換成了注釋方式

自動(dòng)增長,適用于支持自增字段的數(shù)據(jù)庫

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

根據(jù)底層數(shù)據(jù)庫自動(dòng)選擇方式,,需要底層數(shù)據(jù)庫的設(shè)置

MySQL,會(huì)使用自增字段,,需要將主鍵設(shè)置成auto_increment,。

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

使用表存儲(chǔ)生成的主鍵,可以跨數(shù)據(jù)庫,。

每次需要主鍵值時(shí),,查詢名為"hibernate_table"的表,查找主鍵列"gen_pk"值為"2"記錄,,得到這條記錄的"gen_val"值,,根據(jù)這個(gè)值,和allocationSize的值生成主鍵值,。

@Id

@GeneratedValue(strategy = GenerationType.TABLE, generator = "ud")

@TableGenerator(name = "ud",

table = "hibernate_table",

pkColumnName = "gen_pk",

pkColumnValue = "2",

valueColumnName = "gen_val",

initialValue = 2,

allocationSize = 5)

使用序列存儲(chǔ)主鍵值

@Id

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ud")

@SequenceGenerator(name = "ud",

sequenceName = "hibernate_seq",

allocationSize = 1,

initialValue = 2)

13,、小結(jié)

1、為了保證對(duì)象標(biāo)識(shí)符的唯一性與不可變性,,應(yīng)該讓Hibernate來為主鍵賦值,,而不是程序。

2,、正常使用Hibernate維護(hù)主鍵,,最好將主鍵的setter方法設(shè)置成private,從而避免人為或程序修改主鍵,,而使用assigned方式,,就不能用private,否則無法給主鍵賦值,。

2,、Hibernate中唯一一種最簡(jiǎn)單通用的主鍵生成器就是uuid。雖然是個(gè)32位難讀的長字符串,,但是它沒有跨數(shù)據(jù)庫的問題,,將來切換數(shù)據(jù)庫極其簡(jiǎn)單方便,,推薦使用!

3,、自動(dòng)增長字段類型與序列

數(shù)據(jù)庫

自動(dòng)增長字段

序列

MySQL

Oracle

DB2

MS SQL Server

Sybase

HypersonicSQL

PostgreSQL

SAP DB

HSQLDB

Infomix

4,、關(guān)于hilo機(jī)制注意:

hilo算法生成的標(biāo)志只能在一個(gè)數(shù)據(jù)庫中保證唯一。

當(dāng)用戶為Hibernate自行提供連接,,或者Hibernate通過JTA,,從應(yīng)用服務(wù)器的數(shù)據(jù)源獲取數(shù)據(jù)庫連接時(shí),無法使用hilo,,因?yàn)檫@不能保證hilo單獨(dú)在新的數(shù)據(jù)庫連接的事務(wù)中訪問hi值表,,這種情況,如果數(shù)據(jù)庫支持序列,,可以使用seqhilo,。

5、使用identity,、native,、GenerationType.AUTO等方式生成主鍵時(shí),只要用到自增字段,,數(shù)據(jù)庫表的字段必須設(shè)置成自動(dòng)增加的,,否則出錯(cuò)。

6,、還有一些方法未列出來,,例如uuid.hexsequence-identity等,,這些方法不是很常用,,且已被其他方法代替,如uuid.hex,,官方文檔里建議不使用,,而直接使用uuid方法。

7,、Hibernate的各版本主鍵生成策略配置有略微差別,,但實(shí)現(xiàn)基本相同。如,,有的版本默認(rèn)sequence不指定序列名,,則使用名為hibernate_sequence的序列,有的版本則必須指定序列名,。

8,、還可以自定義主鍵生成策略,這里暫時(shí)不討論,只討論官方自帶生成策略,。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多