Hibernate generator 詳解

Hibernate主鍵生成 Key Generator 收藏 
Hibernate 主鍵生成器是負責生成數據表記錄的主鍵,通常有如下幾種常見的主鍵生成方式。
Hibernate主鍵生成方式 Key Generator
主鍵產生器:
首先介紹幾種常見的主鍵生生器:
1) increment
increment: 對 long , short 或 int 的數據列生成自動增長主鍵。
主鍵按數值順序遞增。此方式的實現機制爲在當前應用實例中維持一個變量,以保存着當前的最大值,之後每次需要生成主鍵的時候將此值加1作爲主鍵。這種方式可能產生的問題是:如果當前有多個實例訪問同一個數據庫,那麼由於各個實例各自維護主鍵狀態,不同實例可能生成同樣的主鍵,從而造成主鍵重複異常。因此,如果同一數據庫有多個實
例訪問,此方式必須避免使用。
2) identity
對如 SQL server , MySQL 等支持自動增長列的數據庫,如果數據列的類型是 long, short 或 int ,可使用主鍵生成器生成自動增長主鍵。
3) seqhilo
對如 Oracle , DB2 等支持 Sequence 的數據庫,如果數據列的類型是 long,short 或 int ,可使用該主鍵生成器生成自動增長主鍵。 對 Sequence 解釋可以參見 http://easyworld.javaeye.com/blog/214098
4)uuid:
對字符串列的數據採用 128-位 uuid 算法生成唯一的字符串主鍵。
5) hilo
通過hi/lo 算法實現的主鍵生成機制,需要額外的數據庫表保存主鍵生成歷史狀態。
6) foreign
使用外部表的字段作爲主鍵。
7) native
由Hibernate根據底層數據庫自行判斷採用identity、hilo、sequence其中一種作爲主鍵生成方式,這種方式我在開法過程中經常用到,意思是把主鍵的生成方式交給底層數據庫來決定。
8) assigned
主鍵由外部程序負責生成,無需Hibernate參與。
9) uuid.hex
由Hibernate基於128 位唯一值產生算法生成16 進制數值(編碼後以長度32 的字符串表示)作爲主鍵。
10) uuid.string
與uuid.hex 類似,只是生成的主鍵未進行編碼(長度16)。在某些數據庫中可能出現問題(如PostgreSQL)。
一般而言,利用uuid.hex方式生成主鍵將提供最好的性能和數據庫平臺適應性。
另外由於常用的數據庫,如Oracle、DB2、SQLServer、MySql 等,都提供了易用的主鍵生成機制(Auto-Increase 字段或者Sequence)。我們可以在數據庫提供的主鍵生成機制上,採用generator-class=native的主鍵生成方式。不過值得注意的是,一些數據庫提供的主鍵生成機制在效率上未必最佳,大量併發insert數據時可能會引起表之間的互鎖。數據庫提供的主鍵生成機制,往往是通過在一個內部表中保存當前主鍵狀態(如對於自增型主鍵而言,此內部表中就維護着當前的最大值和遞增量),之後每次插入數據會讀取這個最大值,然後加上遞增量作爲新記錄的主鍵,之後再把這個新的最大值更新回內部表中,這樣,一次Insert操作可能導致數據庫內部多次表讀寫操作,同時伴隨的還有數據的加鎖解鎖操作,這對性能產生了較大影響。因此,對於併發Insert要求較高的系統,推薦採用uuid.hex 作爲主鍵生成機制。
 
1、increment 標識符生成器
 該生成器由Hibernate以遞增的方式爲代理主鍵賦值。在初始化階段,Hibernate讀取表中的最大主鍵值,當插入記錄時,在最大值基礎上遞增,增量爲1。如果有兩個Hibernate應用進程訪問同一個數據庫表,可能出現同時獲取相同的最大值,導致出現相同的主鍵值,從而有一個進程插入失敗!
使用範圍:
-生成標識符機制不依賴於底層數據庫系統,所以他適合於所有的數據庫系統。
-適用於只有單個Hibernate應用進程訪問同一個數據庫的場合,在集羣環境下不推薦使用
-OID必須爲long、int或short型,如果定義爲byte類型,會拋出異常。
2、identity標識符生成器
該生成器由底層數據庫來負責生成標識符,他要求底層數據庫把主鍵定義爲自動增長字段類型。
適用範圍:
-由於依賴於底層數據庫,所以要求底層數據系統必須支持自動增長字段類型。包括:DB2、MySQL、MsSQL、Sybase、HSQLDB、Informix等
-OID必須爲long、int或short型,如果定義爲byte類型,會拋出異常。
3、sequence標識符生成器
該標識符生成器利用底層數據庫提供的序列來生成標識符。
<generator class="sequence">
       <param name="sequence">tester_id_seq</param>
</generator>
在生成的DDL代碼中會生成:
create sequence tester_id_seq;
注:MySQL不支持sequence。
當Hibernate在持久化一個SequenceTester對象時,先從底層數據庫的tester_id_seq序列中獲得一個唯一的序列號,再把它作爲主鍵值。
適用範圍:
-要求底層數據庫必須支持序列,包括:Oracle、DB2、SAP DB、PostgreSQL等。
-OID必須爲long、int或short型,如果定義爲byte類型,會拋出異常。
4、hilo標識符生成器
hilo標識符生成器由HIbernate按照一種high/low算法來生成標識符,他從數據庫的特定表字段中獲取high值
    <id name="id" type="long" column="ID">
    <generator class="hilo">
                <param name="table">hi_value</param>
                <param name="column">next_value</param>
                <param name="max_lo">100</param>
        </generator>
    </id>
上例:high值放在hi_value表的next_value字段中
Hibernate在持久化一個對象時,需要讀取並修改hi_value表中的next_value值。這段操作在單獨的事務中處理。當save時,不使用當前session對象的當前數據庫聯接和事務,而是在一個新的數據庫連接中創建新事務,然後訪問hi_value表。
適用範圍:
-適用於所有的數據庫系統。
-OID必須爲long、int或short型,如果定義爲byte類型,會拋出異常。
-只能在一個數據庫中保證標識符唯一
-當用戶爲Hibernate自行提供數據庫聯接,或者Hibernate通過JTA,從應用服務器的數據源獲得數據庫聯接時無法適用hilo,因爲這樣不能保證hilo在新的數據庫連接的事務中訪問hi_value表。在這種情況下,如果數據庫系統支持序列,可以適用seqhilo生成器。對於支持序列的數據庫系統,可以適用seqhilo,它從序列中獲取high值。
5、native標識符生成器
該生成器依據底層數據庫對自動生成標識符的支持能力,來選擇適用identity、sequence或hilo標識符生成器。能自動判斷底層數據庫提供的生成標識符的機制。
適用範圍:
-適合於跨數據庫平臺開發,即同一個Hibernate應用需要連接多種數據庫系統的場合
-OID必須爲long、int或short型,如果定義爲byte類型,會拋出異常。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章