您好,登錄后才能下訂單哦!
1.increment
由Hibernate從數(shù)據(jù)庫(kù)中去除主鍵的最大值(每個(gè)session只取一次),以該值為基礎(chǔ),每次增量為1,在內(nèi)存中生成主鍵,不依賴于底層的數(shù)據(jù)庫(kù),因此可以跨數(shù)據(jù)庫(kù)。
<id name="id" column="id"> <generator class="increment" /> </id>
Hibernate調(diào)用org.hibernate.id.IncrementGenerator類里面的generate()方法,使用select max(idColumnName) from tableName語(yǔ)句獲取主鍵最大值。該方法被聲明成了synchronized,所以在一個(gè)獨(dú)立的Java虛擬機(jī)內(nèi)部是沒有問題的,然而,在多個(gè)JVM同時(shí)并發(fā)訪問數(shù)據(jù)庫(kù)select max時(shí)就可能取出相同的值,再insert就會(huì)發(fā)生Dumplicate entry的錯(cuò)誤。所以只能有一個(gè)Hibernate應(yīng)用進(jìn)程訪問數(shù)據(jù)庫(kù),否則就可能產(chǎn)生主鍵沖突,所以不適合多進(jìn)程并發(fā)更新數(shù)據(jù)庫(kù),適合單一進(jìn)程訪問數(shù)據(jù)庫(kù),不能用于群集環(huán)境。
特點(diǎn):跨數(shù)據(jù)庫(kù),不適合多進(jìn)程并發(fā)更新數(shù)據(jù)庫(kù),適合單一進(jìn)程訪問數(shù)據(jù)庫(kù),不能用于群集環(huán)境。
2.sequence
采用數(shù)據(jù)庫(kù)提供的sequence機(jī)制生成主鍵,需要數(shù)據(jù)庫(kù)支持sequence。如oralce、DB、SAP DB、PostgerSQL、McKoi中的sequence。MySQL這種不支持sequence的數(shù)據(jù)庫(kù)則不行(可以使用identity)。
<generator class="sequence"> <param name="sequence">hibernate_id</param> </generator>
<param name="sequence">hibernate_id</param> 指定sequence的名稱
Hibernate生成主鍵時(shí),查找sequence并賦給主鍵值,主鍵值由數(shù)據(jù)庫(kù)生成,Hibernate不負(fù)責(zé)維護(hù),使用時(shí)必須先創(chuàng)建一個(gè)sequence,如果不指定sequence名稱,則使用Hibernate默認(rèn)的sequence,名稱為hibernate_sequence,前提要在數(shù)據(jù)庫(kù)中創(chuàng)建該sequence。
特點(diǎn):只能在支持序列的數(shù)據(jù)庫(kù)中使用,如Oracle。
3.identity
identity由底層數(shù)據(jù)庫(kù)生成標(biāo)識(shí)符。identity是由數(shù)據(jù)庫(kù)自己生成的,但這個(gè)主鍵必須設(shè)置為自增長(zhǎng),使用identity的前提條件是底層數(shù)據(jù)庫(kù)支持自動(dòng)增長(zhǎng)字段類型,如DB2、SQL Server、MySQL、Sybase和HypersonicSQL等,Oracle這類沒有自增字段的則不支持。
<id name="id" column="id">
<generator class="identity" />
</id>
例:如果使用MySQL數(shù)據(jù)庫(kù),則主鍵字段必須設(shè)置成auto_increment。
id int(11) primary key auto_increment
特點(diǎn):只能用在支持自動(dòng)增長(zhǎng)的字段數(shù)據(jù)庫(kù)中使用,如MySQL。
4.native
native由hibernate根據(jù)使用的數(shù)據(jù)庫(kù)自行判斷采用identity、hilo、sequence其中一種作為主鍵生成方式,靈活性很強(qiáng)。如果能支持identity則使用identity,如果支持sequence則使用sequence。
<id name="id" column="id">
<generator class="native" />
</id>
例如MySQL使用identity,Oracle使用sequence
注意:如果Hibernate自動(dòng)選擇sequence或者h(yuǎn)ilo,則所有的表的主鍵都會(huì)從Hibernate默認(rèn)的sequence或hilo表中取。并且,有的數(shù)據(jù)庫(kù)對(duì)于默認(rèn)情況主鍵生成測(cè)試的支持,效率并不是很高。
使用sequence或hilo時(shí),可以加入?yún)?shù),指定sequence名稱或hi值表名稱等,如
<param name="sequence">hibernate_id</param>
特點(diǎn):根據(jù)數(shù)據(jù)庫(kù)自動(dòng)選擇,項(xiàng)目中如果用到多個(gè)數(shù)據(jù)庫(kù)時(shí),可以使用這種方式,使用時(shí)需要設(shè)置表的自增字段或建立序列,建立表等。
5.uuid
UUID:Universally 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-9 或 a-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)長(zhǎng)度較大,32位(Hibernate將UUID中間的“-”刪除了)的字符串,占用存儲(chǔ)空間大,但是有兩個(gè)很重要的優(yōu)點(diǎn),Hibernate在維護(hù)主鍵時(shí),不用去數(shù)據(jù)庫(kù)查詢,從而提高效率,而且它是跨數(shù)據(jù)庫(kù)的,以后切換數(shù)據(jù)庫(kù)極其方便。
特點(diǎn):uuid長(zhǎng)度大,占用空間大,跨數(shù)據(jù)庫(kù),不用訪問數(shù)據(jù)庫(kù)就生成主鍵值,所以效率高且能保證唯一性,移植非常方便,推薦使用。
6.guid
GUID:Globally Unique Identifier全球唯一標(biāo)識(shí)符,也稱作 UUID,是一個(gè)128位長(zhǎng)的數(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ù)庫(kù),獲得一個(gè)uuid字符串,該字符串就是主鍵值,該值唯一,缺點(diǎn)長(zhǎng)度較大,支持?jǐn)?shù)據(jù)庫(kù)有限,優(yōu)點(diǎn)同uuid,跨數(shù)據(jù)庫(kù),但是仍然需要訪問數(shù)據(jù)庫(kù)。
注意:長(zhǎng)度因數(shù)據(jù)庫(kù)不同而不同
MySQL中使用select uuid()語(yǔ)句獲得的為36位(包含標(biāo)準(zhǔn)格式的“-”)
Oracle中,使用select rawtohex(sys_guid()) from dual語(yǔ)句獲得的為32位(不包含“-”)
特點(diǎn):需要數(shù)據(jù)庫(kù)支持查詢uuid,生成時(shí)需要查詢數(shù)據(jù)庫(kù),效率沒有uuid高,推薦使用uuid。
7.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)系中。
總結(jié)
以上就是本文關(guān)于Java探索之Hibernate主鍵生成策略詳細(xì)介紹的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:Hibernate實(shí)現(xiàn)悲觀鎖和樂觀鎖代碼介紹、詳細(xì)解讀Hibernate的緩存機(jī)制等,有什么問題可以隨時(shí)留言,歡迎交流討論。感謝朋友們對(duì)本站的支持!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。