1. 程式人生 > >Hibernate (三)主鍵生成方式

Hibernate (三)主鍵生成方式

參考文獻

http://blog.csdn.net/wanghuan203/article/details/7562395

http://www.cnblogs.com/hoobey/p/5508992.html

宣告:主鍵生成配置直接摘抄了http://www.cnblogs.com/hoobey/p/5508992.html這篇部落格的Hibernate各種主鍵生成策略與配置詳解,主要是人家總結的太詳細了,我就直接用了,特此感謝。

    hibernate提供的主鍵生成策略,使我們可以在實體類的對映xml檔案中設定關鍵字來告訴hibernate我們要使用的主鍵生成方式,然後hibernate會根據設定完成資料庫的主鍵控制。

一、實體對映檔案(*.hbm.xml)中對id生成策略配置格式

1:user的實體類user.java

package com.entity.hibernate;  
  
public class User {  
  
       private int id;          
       private String name;   
       public User(){}  
       public int getId() {  
           return id;  
       }  
       public void setId(int id) {  
           this.id = id;  
       }  
       public String getName() {  
           return name;  
       }  
       public void setName(String name) {  
           this.name = name;  
       }  
  
} 
2:user對應的對映檔案user.hbm.xml
<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC   
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
<hibernate-mapping>  
   <class name="com.entity.hibernate.User">  
            <id name="id">  
                <generator class="uuid"/>  
            </id>  
            <property name="name"/>                  
   </class>  
</hibernate-mapping>  
主鍵生成配置
<id name="id" column="表主鍵欄位名" type="java.lang.Integer">
    <generator class="設定主鍵生成策略型別"/>
</id>
二、主鍵生成配置

1:assigned
主鍵由外部程式負責生成,在 save() 之前必須指定一個。Hibernate不負責維護主鍵生成。與Hibernate和底層資料庫都無關,可以跨資料庫。在儲存物件前,必須要使用主鍵的setter方法給主鍵賦值,至於這個值怎麼生成,完全由自己決定,這種方法應該儘量避免。

<id name="id" column="id">
    <generator class="assigned" />
</id>
特點:可以跨資料庫,人為控制主鍵生成,應儘量避免。

2:increment
由Hibernate從資料庫中取出主鍵的最大值(每個session只取1次),以該值為基礎,每次增量為1,在記憶體中生成主鍵,不依賴於底層的資料庫,因此可以跨資料庫。

<id name="id" column="id">
    <generator class="increment" />
</id>
Hibernate呼叫org.hibernate.id.IncrementGenerator類裡面的generate()方法,使用select max(idColumnName) from tableName語句獲取主鍵最大值。該方法被宣告成了synchronized,所以在一個獨立的Java虛擬機器內部是沒有問題的,然而,在多個JVM同時併發訪問資料庫select max時就可能取出相同的值,再insert就會發生Dumplicate entry的錯誤。所以只能有一個Hibernate應用程序訪問資料庫,否則就可能產生主鍵衝突,所以不適合多程序併發更新資料庫,適合單一程序訪問資料庫,不能用於群集環境。
官方文件:只有在沒有其他程序往同一張表中插入資料時才能使用,在叢集下不要使用。
特點:跨資料庫,不適合多程序併發更新資料庫,適合單一程序訪問資料庫,不能用於群集環境。
3:hilo
hilo(高低位方式high low)是hibernate中最常用的一種生成方式,需要一張額外的表儲存hi的值。儲存hi值的表至少有一條記錄(只與第一條記錄有關),否則會出現錯誤。可以跨資料庫。
<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> 指定低位的最大值
也可以省略table和column配置,其預設的表為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值:讀取並記錄資料庫的hibernate_unique_key表中next_hi欄位的值,資料庫中此欄位值加1儲存。
2)獲得lo值:從0到max_lo迴圈取值,差值為1,當值為max_lo值時,重新獲取hi值,然後lo值繼續從0到max_lo迴圈。
3)根據公式 hi * (max_lo + 1) + lo計算生成主鍵值。
注意:當hi值是0的時候,那麼第一個值不是0*(max_lo+1)+0=0,而是lo跳過0從1開始,直接是1、2、3……
那max_lo配置多大合適呢?
這要根據具體情況而定,如果系統一般不重啟,而且需要用此表建立大量的主鍵,可以吧max_lo配置大一點,這樣可以減少讀取資料表的次數,提高效率;反之,如果伺服器經常重啟,可以吧max_lo配置小一點,可以避免每次重啟主鍵之間的間隔太大,造成主鍵值主鍵不連貫。
特點:跨資料庫,hilo演算法生成的標誌只能在一個數據庫中保證唯一。
4:seqhilo
與hilo類似,通過hi/lo演算法實現的主鍵生成機制,只是將hilo中的資料表換成了序列sequence,需要資料庫中先建立sequence,適用於支援sequence的資料庫,如Oracle。
<id name="id" column="id">
    <generator class="seqhilo">
        <param name="sequence">hibernate_seq</param>
        <param name="max_lo">100</param>
    </generator>
</id>
特點:與hilo類似,只能在支援序列的資料庫中使用。

5:sequence
採用資料庫提供的sequence機制生成主鍵,需要資料庫支援sequence。如oralce、DB、SAP DB、PostgerSQL、McKoi中的sequence。MySQL這種不支援sequence的資料庫則不行(可以使用identity)。

<id name="id" column="id">
    <generator class="sequence">
        <param name="sequence">hibernate_id</param>
    </generator>
    <param name="sequence">hibernate_id</param> 指定sequence的名稱
</id>
Hibernate生成主鍵時,查詢sequence並賦給主鍵值,主鍵值由資料庫生成,Hibernate不負責維護,使用時必須先建立一個sequence,如果不指定sequence名稱,則使用Hibernate預設的sequence,名稱為hibernate_sequence,前提要在資料庫中建立該sequence。
特點:只能在支援序列的資料庫中使用,如Oracle。

6:identity

identity由底層資料庫生成識別符號。identity是由資料庫自己生成的,但這個主鍵必須設定為自增長,使用identity的前提條件是底層資料庫支援自動增長欄位型別,如DB2、SQL Server、MySQL、Sybase和HypersonicSQL等,Oracle這類沒有自增欄位的則不支援。

<id name="id" column="id">
    <generator class="identity" />
</id>
例:如果使用MySQL資料庫,則主鍵欄位必須設定成auto_increment。
id int(11) primary key auto_increment
特點:只能用在支援自動增長的欄位資料庫中使用,如MySQL。
7:native
native由hibernate根據使用的資料庫自行判斷採用identity、hilo、sequence其中一種作為主鍵生成方式,靈活性很強。如果能支援identity則使用identity,如果支援sequence則使用sequence。
<id name="id" column="id">
    <generator class="native" />
</id>
例如MySQL使用identity,Oracle使用sequence
注意:如果Hibernate自動選擇sequence或者hilo,則所有的表的主鍵都會從Hibernate預設的sequence或hilo表中取。並且,有的資料庫對於預設情況主鍵生成測試的支援,效率並不是很高。
使用sequence或hilo時,可以加入引數,指定sequence名稱或hi值表名稱等,如
<param name="sequence">hibernate_id</param>
特點:根據資料庫自動選擇,專案中如果用到多個數據庫時,可以使用這種方式,使用時需要設定表的自增欄位或建立序列,建立表等。
8:uuid
UUID:Universally Unique Identifier,是指在一臺機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的。按照開放軟體基金會(OSF)制定的標準計算,用到了乙太網卡地址、納秒級時間、晶片ID碼和許多可能的數字,標準的UUID格式為:xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx (8-4-4-4-12)。其中每個 x 是 0-9 或 a-f 範圍內的一個十六進位制的數字。
<id name="id" column="id">
    <generator class="uuid" />
</id>
Hibernate在儲存物件時,生成一個UUID字串作為主鍵,保證了唯一性,但其並無任何業務邏輯意義,只能作為主鍵,唯一缺點長度較大,32位(Hibernate將UUID中間的“-”刪除了)的字串,佔用儲存空間大,但是有兩個很重要的優點,Hibernate在維護主鍵時,不用去資料庫查詢,從而提高效率,而且它是跨資料庫的,以後切換資料庫極其方便。
特點:uuid長度大,佔用空間大,跨資料庫,不用訪問資料庫就生成主鍵值,所以效率高且能保證唯一性,移植非常方便,推薦使用。
9:guid
GUID:Globally Unique Identifier全球唯一識別符號,也稱作 UUID,是一個128位長的數字,用16進製表示。演算法的核心思想是結合機器的網絡卡、當地時間、一個隨即數來生成GUID。從理論上講,如果一臺機器每秒產生10000000個GUID,則可以保證(概率意義上)3240年不重複。
<id name="id" column="id">
    <generator class="guid" />
</id>
Hibernate在維護主鍵時,先查詢資料庫,獲得一個uuid字串,該字串就是主鍵值,該值唯一,缺點長度較大,支援資料庫有限,優點同uuid,跨資料庫,但是仍然需要訪問資料庫。
注意:長度因資料庫不同而不同
MySQL中使用select uuid()語句獲得的為36位(包含標準格式的“-”)
Oracle中,使用select rawtohex(sys_guid()) from dual語句獲得的為32位(不包含“-”) 
特點:需要資料庫支援查詢uuid,生成時需要查詢資料庫,效率沒有uuid高,推薦使用uuid。

10:foreign
使用另外一個相關聯的物件的主鍵作為該物件主鍵。主要用於一對一關係中。

<id name="id" column="id">
    <generator class="foreign">
        <param name="property">user</param>
    </generator>
</id>
<one-to-one name="user" class="User" constrained="true" />
該例使用domain.User的主鍵作為本類對映的主鍵。
特點:很少使用,大多用在一對一關係中。

三、其他註解方式配置

注:“ud”是自定義的策略名,自定義起名

註釋方式與配置檔案底層實現方式相同,只是配置的方式換成了註釋方式
自動增長,適用於支援自增欄位的資料庫

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
根據底層資料庫自動選擇方式,需要底層資料庫的設定
如MySQL,會使用自增欄位,需要將主鍵設定成auto_increment。
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
使用表儲存生成的主鍵,可以跨資料庫。
每次需要主鍵值時,查詢名為"hibernate_table"的表,查詢主鍵列"gen_pk"值為"2"記錄,得到這條記錄的"gen_val"值,根據這個值,和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)
使用序列儲存主鍵值
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ud")
@SequenceGenerator(name = "ud",
sequenceName = "hibernate_seq",
allocationSize = 1,
initialValue = 2)



相關推薦

Hibernate 生成方式

參考文獻: http://blog.csdn.net/wanghuan203/article/details/7562395 http://www.cnblogs.com/hoobey/p/5508992.html 宣告:主鍵生成配置直接摘抄了http://www.cnbl

hibernate基礎——生成策略與flush快取清理

在瞭解此文前,請首先閱讀: 在使用hibernate時,我們還是很有必要將hibernate的內部實現原理來搞清楚一下的。比如,hibernate在儲存一個物件時, 它的

hibernate的11種生成方式

hibernate提供了很多種主鍵的生成方式,以解決實際開發中各種不同的資料庫以及其主鍵的策略,以前的時候,也有用過很多種,但是都不全面,這次在書上看到了,便記錄下來,方便以後檢視,使用。 1.

(轉 Hibernate持久化類與生成策略

bject 規則 修飾符 cti arc arch 斷點 可能 策略 http://blog.csdn.net/yerenyuan_pku/article/details/65462930 Hibernate持久化類 什麽是持久化類呢?在Hibernate中持久化類的英

hibernate 生成方式

程序 操作 外部 解鎖 數據庫表 body 要求 讀寫 字符串表 1)assigned主鍵由外部程序負責生成,無需Hibernate參與。2)hilo通過hi/lo 算法實現的主鍵生成機制,需要額外的數據庫表保存主鍵生成歷史狀態。3)seqhilo與hilo 類似,通過hi

Hibernate生成方式

Key Generator主鍵產生器可選項說明:1) assigned主鍵由外部程式負責生成,無需Hibernate參與。2) hilo通過hi/lo 演算法實現的主鍵生成機制,需要額外的資料庫表儲存主鍵生成歷史狀態。3) seqhilo與hilo 類似,通過hi/lo 演算法實現的主鍵生成機制,只是主鍵歷史

Hibernate各種生成方式配置

1、assigned 主鍵由外部程式負責生成,在save()之前必須指定一個。Hibernate不負責維護主鍵生成。與Hibernate和底層資料庫都無關,可以跨資料庫。在儲存物件前,必須要使用主鍵的setter方法給主鍵賦值,至於這個值怎麼生成,完全由自己決定,這種方法應

Hibernate的uuid生成方式

從hibernate3.0開始已經不再支援uuid.string,檢視changelog可以發現: Changes in version 3.0 beta 1 (21.12.2004) * removed uuid.string and renamed uuid.hex to plain uuid,hiber

HibernateHibernate表操作、多對多配置

1.2 Hibernate的一對多關聯對映 1.2.1 資料庫表與表之間的關係 1.2.1.1 一對多關係 什麼樣關係屬於一對多?   一個部門對應多個員工,一個員工只能屬於某一個部門。 一個客戶對應多個聯絡人,一個聯絡人只能屬於某一個客戶。 一對多的建表原

Hibernate工具類和生成策略

建立hibernate的好處 1.方便獲取session繪畫,用來操作資料庫 2.用來檢測所有的對映檔案配置是否準確 package com.two.util; import org.hibernate.Session; import org.hibernate.SessionFact

Flume學習之路 Flume的配置方式

dfs- 來源 rep RoCE list 數據 日誌 appserver 路徑 一、單一代理流配置 1.1 官網介紹 http://flume.apache.org/FlumeUserGuide.html#avro-source 通過一個通道將來源和接收器鏈接。需要列出源

RNN入門利用LSTM生成旅遊點評

介紹   前幾天,某個公眾號發文質疑馬蜂窩網站,認為它搬運其它網站的旅遊點評,對此,馬蜂窩網站迅速地做出了迴應。相信大多數關注時事的群眾已經瞭解了整個事情的經過,在這裡,我們且不論這件事的是是非非,也不關心它是否是通過爬蟲等其他技術手段實現的。本文將會展示一種自動生成旅遊點評的技術手

MySql必知必會實戰練習、外來、sql約束、聯結表 MySql資料庫約束

  本博將對主鍵、外來鍵、MySql資料庫約束和聯結表的相關特性進行總結和實戰 1. 主鍵   表中的每一行都應該具有可以唯一標識自己的一列(或一組列),而這個承擔標識作用的列稱為主鍵   如果沒有主鍵,資料的管理會十分混亂。比如會存在多條一模一樣的記錄,刪除和修改特定行十分困難 (1)哪些列可以作為

程序間通訊方式-----訊息佇列

訊息佇列 訊息佇列,是訊息的連結表,存放在核心中。一個訊息佇列由一個識別符號(即佇列ID)來標識。使用者程序可以向訊息佇列新增訊息,也可以向訊息佇列讀取訊息。 同管道檔案相比,訊息佇列中的每個訊息指定特定的訊息型別,接收的時候可以不需要按照佇列次序讀取,可以根據自定義型別

Spring 學習筆記IOC之XML方式配置 第二回Bean節點屬性的配置

<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/X

Spring 學習筆記IOC之XML方式配置 第一回 javaBean的配置與獲取

IOC的兩種方式: XML方式 註解方式 XML方式 需要的jar包   spring-beans-4.3.3.RELEASE.jar spring-context-4.3.3.RELEASE.jar spring-context-support

使用註解風格學習Hibernate和JPA的生成策略

                      主鍵是關係資料庫中的一個基本概念,它用來保證記錄的唯一性。簡單來說,就是同一張資料庫表中,不允許存在多條相同主鍵的記錄。主鍵生成策略,就是當向資料庫表中插入記錄的時候,這個記錄的主鍵該如何生成。絕大部分情況下,主鍵都是沒有業務含義的,所以開發者不會、也不需要,顯示地

HibernateHibernate核心類,介面

一,Configuration       Configuration是 一個介面,作用是對它進行啟動,以及負責管理Configuration的配置資訊,包括以下內容: Hibernate執行的底層資訊:資料庫的URL,使用者名稱,密碼,JDBC驅動,資料庫的Dialec

Machine Learning第八講【非監督學習】--成分分析PCA

一、Principal Component Analysis Problem Formulation(主成分分析構思) 首先來看一下PCA的基本原理: PCA會選擇投影誤差最小的一條線,由圖中可以看出,當這條線是我們所求時,投影誤差比較小,而投影誤差比較大時,一定是這條線偏離最優直線。

webpack4系列教程:自動生成專案中的HTML檔案

傳送門: webpack4系列教程(一):初識webpack webpack4系列教程(二):建立專案,打包第一個JS檔案   1. webpack中的CommonJS和ES Mudule 規範 1.1 CommonJs規範 CommonJs規範的出發點:JS沒