原文連接:http://www.yiidian.com/hibernate/hibernate-generator.htmlhtml
Hibernate提供的主鍵生成策略,使咱們能夠在實體類的映射xml文件中設定關鍵字來告訴hibernate咱們要使用的主鍵生成方式,而後hibernate會根據設定完成數據庫的主鍵控制。java
用戶User的實體類User.javamysql
package com.yiidian.domain; 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.yiidian.domain.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>
對主鍵值採起自動順序增加的方式生成新的主鍵,值默認從1開始。 原理:在當前應用實例中維持一個變量,以保存當前最大值,以後每次須要生成主鍵值的時候將此值加1做爲主鍵.不依賴於底層的數據庫,所以全部的數據庫均可以使用 缺點:經過increment的生成主鍵的原理可推斷,此種主鍵生成策略不適用於集羣、同一時段大量用戶併發訪問的系統,既當大量用戶同一時間段同時進行插入操做的時候,可能存在取得相同的最大值而後再同時+1的狀況,這個時候就會形成主鍵衝突。所以,若是同一數據庫有多個實例訪問,此方式必須避免使用。sql
原理UUID使用128位UUID算法生成主鍵,可以保證網絡環境下的主鍵惟一性,也就可以保證在不一樣數據庫及不一樣服務器下主鍵的惟一性。因此使用於全部數據庫。 特色;可以保證數據庫中的主鍵惟一性,可是在生成的主鍵佔用比較多的存貯空間數據庫
原理:經過hi/lo 算法(Hilo使用高低位算法生成主鍵,高低位算法使用一個高位值和一個低位值,而後把算法獲得的兩個值拼接起來)實現的主鍵生成機制,須要額外的數據庫表保存主鍵生成歷史狀態。 特色:須要額外的數據庫表和字段提供高位值來源。默認狀況下使用的表是 hibernate_unique_key,默認字段叫做next_hi。next_hi必須有一條記錄不然會出現錯誤。須要額外的數據庫表的支持,能保證同一個數據庫中主鍵的惟一性,但不能保證多個數據庫之間主鍵的惟一性。Hilo主鍵生成方式由Hibernate 維護,因此Hilo方式與底層數據庫無關。服務器
sequence實際是就是一張單行單列的表。 實現原理:調用數據庫中底層存在的sequence生成主鍵,須要底層數據庫的支持序列,所以他是依賴於數據庫的。 支持sequence的數據庫有:Oracle 、DB2(Mysql/SQlServer不支持)、PostgreSql、SAPDb等網絡
根據底層數據庫,來支持自動增加,不一樣的數據庫用不一樣的主鍵增加方式。 特色: 與底層數據庫有關,要求數據庫支持Identity,如MySQl中是auto_increment, SQL Server 中是Identity。支持的數據庫有MySql、SQL Server、DB二、Sybase和HypersonicSQL。 好處:在建表的時候指定了id爲自動增加,實際開發中就不須要本身定義插入數據庫的主鍵值,系統會自動順序遞增一個值 。Identity無需Hibernate和用戶的干涉,使用較爲方便,但因爲依賴於數據庫,因此不便於在不一樣的數據庫之間移植程序。 session
做用:根據數據庫的類型,自動在sequence 、identity和,hilo進行切換。 實現自動切換的依據:根據Hibernate配置文件中的方言來判斷是Oracle仍是Mysql、SqlServer,而後針對數據庫的類型抉擇 sequence仍是identity做爲主鍵生成策略。 用處:因爲Hibernate會根據底層數據庫採用不一樣的映射方式,所以靈活性高,便於程序移植,項目中若是用到多個數據庫時,可使用這種方式。
做用:用於手工分配主鍵生成器,一旦指定爲這個了,Hibernate就不在自動爲程序作主鍵生成器了。沒有指定<generator>標籤時,默認就是assigned主鍵的生成方式 使用方法:在程序中session.save();以前,由程序員本身指定主鍵值爲多少。 例如:user.setId(1);這就是在程序中程序員手動爲用戶表指定主鍵值爲1。
只適用基於共享主鍵的一對一關聯映射的時候使用。即一個對象的主鍵是參照的另外一張表的主鍵生成的。
UUID,increment、Hilo、assigned:對數據庫無依賴 identity:依賴Mysql或sql server,主鍵值不禁hibernate維護 sequence:適合於oracle等支持序列的dbms,主鍵值不禁hibernate維護,由序列產生。 native:根據底層數據庫的具體特性選擇適合的主鍵生成策略,若是是mysql或sqlserver,選擇identity,若是是oracle,選擇sequence。
通常來講推薦UUID,由於生成主鍵惟一,且對數據庫無依賴,可移植性強。
因爲經常使用的數據庫,如Oracle、DB二、SQLServer、MySql 等,都提供了易用的主鍵生成機制(Auto-Increase 字段或者Sequence)。咱們能夠在數據庫提供的主鍵生成機制上,採用native,sequence或者identity的主鍵生成方式。
不過值得注意的是,一些數據庫提供的主鍵生成機制在效率上未必最佳大量併發insert數據時可能會引發表之間的互鎖。
所以,對於併發Insert要求較高的系統,推薦採用uuid做爲主鍵生成機制。
總之,hibernate主鍵生成器選擇,還要具體狀況具體分析。通常而言,利用uuid方式生成主鍵將提供最好的性能和數據庫平臺適應性。
歡迎關注個人公衆號::一點教程。得到獨家整理的學習資源和平常乾貨推送。 若是您對個人系列教程感興趣,也能夠關注個人網站:yiidian.com