Hibernate主鍵生成策略總結



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

 

一、首先通過舉例子來了解實體映射文件(*.hbm.xml)中對id生成策略配置格式

    用戶User的實體類User.java

    

package com.bjpowernode.hibernate;

import java.util.Date;

public class User {

       private String id;        
       private String name; 
       public User(){}
       public String getId() {
           return id;
       }
       public void setId(String id) {
           this.id = id;
       }
       public String getName() {
           return name;
       }
       public void setName(String name) {
           this.name = name;
       }

}


 

 

User.java對應的映射文件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.bjpowernode.hibernate.User">
            <id name="id">

                     <generator class="uuid"/>

            </id>
            <property name="name"/>
            <property name="password"/>                   
   </class>

</hibernate-mapping>


 

   其中

   <id name="id" column="表主鍵字段名" type="java.lang.Integer">

        <generator class="設置主鍵生成策略類型"/>

   </id>

 

    二、Hibernate常用的主鍵生成策略的原理、特點、應用場合

    關於映射文件的問題下次再介紹,這次主要總結hibernate常用主鍵生成策略。

   (1)increment

       a)對主鍵值採取自動順序增長的方式生成新的主鍵,值默認從1開始。

       b)原理:在當前應用實例中維持一個變量,以保存當前最大值,之後每次需要生成主鍵值的時候將此值加1作爲主鍵.不依賴於底層的數據庫,因此所有的數據庫都可以使用

       c)缺點:通過increment的生成主鍵的原理可推斷,此種主鍵生成策略不適用於集羣、同一時段大量用戶併發訪問的系統,既當大量用戶同一時間段同時進行插入操作的時候,可能存在取得相同的最大值然後再同時+1的情況,這個時候就會造成主鍵衝突。因此,如果同一數據庫有多個實例訪問,此方式必須避免使用。

 

   (2)UUID

       a)原理UUID使用128位UUID算法生成主鍵,能夠保證網絡環境下的主鍵唯一性,也就能夠保證在不同數據庫及不同服務器下主鍵的唯一性。所以使用於所有數據庫。

       b)特點;能夠保證數據庫中的主鍵唯一性,但是在生成的主鍵佔用比較多的存貯空間 

 

   (3)Hilo

      a)原理:通過hi/lo 算法(Hilo使用高低位算法生成主鍵,高低位算法使用一個高位值和一個低位值,然後把算法得到的兩個值拼接起來)實現的主鍵生成機制,需要額外的數據庫表保存主鍵生成歷史狀態。

       b)特點:需要額外的數據庫表和字段提供高位值來源。默認情況下使用的表是   hibernate_unique_key,默認字段叫作next_hi。next_hi必須有一條記錄否則會出現錯誤。需要額外的數據庫表的支持,能保證同一個數據庫中主鍵的唯一性,但不能保證多個數據庫之間主鍵的唯一性。Hilo主鍵生成方式由Hibernate 維護,所以Hilo方式與底層數據庫無關。

 

   (4)sequence

       a)sequence實際是就是一張單行單列的表。

       b)實現原理:調用數據庫中底層存在的sequence生成主鍵,需要底層數據庫的支持序列,因此他是依賴於數據庫的。

       c)支持sequence的數據庫有:Oracle 、DB2(Mysql/SQlServer不支持)、PostgreSql、SAPDb等

 

   (5)identity

       a)根據底層數據庫,來支持自動增長,不同的數據庫用不同的主鍵增長方式。

       b)特點: 與底層數據庫有關,要求數據庫支持Identity,如MySQl中是auto_increment, SQL Server 中是Identity。支持的數據庫有MySql、SQL Server、DB2、Sybase和HypersonicSQL。

       c)好處:在建表的時候指定了id爲自動增長,實際開發中就不需要自己定義插入數據庫的主鍵值,系統會自動順序遞增一個值 。Identity無需Hibernate和用戶的干涉,使用較爲方便,但由於依賴於數據庫,所以不便於在不同的數據庫之間移植程序。

  

   (6)native

       a)作用:根據數據庫的類型,自動在sequence 、identity和,hilo進行切換。

       b)實現自動切換的依據:根據Hibernate配置文件中的方言來判斷是Oracle還是Mysql、SqlServer,然後針對數據庫的類型抉擇 sequence還是identity作爲主鍵生成策略。

       c)用處:由於Hibernate會根據底層數據庫採用不同的映射方式,因此靈活性高,便於程序移植,項目中如果用到多個數據庫時,可以使用這種方式。

 

   (7)assigned

       a)作用:用於手工分配主鍵生成器,一旦指定爲這個了,Hibernate就不在自動爲程序做主鍵生成器了。沒有指定<generator>標籤時,默認就是assigned主鍵的生成方式

       b)使用方法:在程序中session.save();之前,由程序員自己指定主鍵值爲多少。

         例如:user.setId(1);這就是在程序中程序員手動爲用戶表指定主鍵值爲1。

   (8)foreign

       只適用基於共享主鍵的一對一關聯映射的時候使用。即一個對象的主鍵是參照的另一張表的主鍵生成的。

  

   對數據庫的依賴性總結

    UUID,increment、Hilo、assigned:對數據庫無依賴

    identity:依賴Mysql或sql server,主鍵值不由hibernate維護

    sequence:適合於oracle等支持序列的dbms,主鍵值不由hibernate維護,由序列產生。

    native:根據底層數據庫的具體特性選擇適合的主鍵生成策略,如果是mysql或sqlserver,選擇identity,如果是oracle,選擇sequence。

 

 

   關於主鍵生成策略的選擇:

    一般來說推薦UUID,因爲生成主鍵唯一,且對數據庫無依賴,可移植性強。

    由於常用的數據庫,如Oracle、DB2、SQLServer、MySql 等,都提供了易用的主鍵生成機制(Auto-Increase 字段或者Sequence)。我們可以在數據庫提供的主鍵生成機制上,採用native,sequence或者identity的主鍵生成方式。

    不過值得注意的是,一些數據庫提供的主鍵生成機制在效率上未必最佳大量併發insert數據時可能會引起表之間的互鎖。

    因此,對於併發Insert要求較高的系統,推薦採用uuid作爲主鍵生成機制。

    總之,hibernate主鍵生成器選擇,還要具體情況具體分析。一般而言,利用uuid方式生成主鍵將提供最好的性能和數據庫平臺適應性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章