hibernate之主鍵生成策略


一、主鍵類型
1.自然主鍵(主鍵本身就是表中的一個字段,實體中一個具體的屬性)
表中已經具有某字段,並且該字段具有業務含義作為主鍵,稱之為自然主鍵。

例如:在person表中的身份證號,既是唯一的,又可以單獨標識一個person

2.代理主鍵(主鍵不是實體中某個具體的屬性,而是一個不相關的字段)
表中原本不存在的字段,且不具備業務含義的字段作為主鍵,稱之為代理主鍵。更合理的方式是使用代理主鍵。

 

二、主鍵生成策略
主鍵生成策略,就是每條記錄錄入時,主鍵的生成規則。Hibernate中,提供了幾個內置的主鍵生成策略,其常用主鍵生成策略的名稱和描述如下

1.代理主鍵
identity(主鍵自增)
適用於long、short或int類型主鍵,采用底層數據庫本身提供的主鍵生成標識符。在DB2、MySQL、MS SQL Server、Sybase和HypersonicSQL數據庫中可以使用該生成器,該生成器要求在數據庫中把主鍵定義成為自增類型。Oracle沒有自動增長

sequence(序列)
適用於long、short或int類型主鍵,Hibernate根據底層數據庫序列生成標識符。條件是數據庫支持序列。如oralce、DB、SAP DB、PostgerSQL、McKoi中的sequence,MySQL這種不支持sequence

increment(主鍵自增,單線程,maxID+1)
適用於long、short或int類型主鍵,由Hibernate提供自動遞增的方式生成唯一標識符,每次增量為1。只有當沒有其他進程向同一張表中插入數據時才可以使用,不能再多線程環境下使用

hilo(主鍵自增,高低位算法)
hilo(高低位方式high low)是hibernate中最常用的一種生成方式,需要一張額外的表保存hi的值。保存hi值的表至少有一條記錄(只與第一條記錄有關),否則會出現錯誤。跨數據庫,hilo算法生成的標志只能在一個數據庫中保證唯一

native(hilo+identity+sequence三選一)
根據底層數據庫對自動生成標識符的能力來選擇i dentity、sequence、hilo三種生成器中的一種,適合跨數據庫平台開發

uuid(隨機字符串作主鍵)
Hibernate采用128位的UUID算法來生成標識符。該算法能夠在網絡環境中生成唯一的字符串標識符,其UUID被編碼為一個長度為32位的十六進制字符串。按照開放軟件基金會(OSF)制定的標准計算,用到了以太網卡地址、納秒級時間、芯片ID碼和許多可能的數字

uuid長度大,占用空間大,跨數據庫,不用訪問數據庫就生成主鍵值,所以效率高且能保證唯一性,移植非常方便,推薦使用。

guid(全球唯一標識符)
全球唯一標識符,也稱作 UUID,是一個128位長的數字,用16進制表示。算法的核心思想是結合機器的網卡、當地時間、一個隨即數來生成GUID。

Hibernate在維護主鍵時,先查詢數據庫,獲得一個uuid字符串,該字符串就是主鍵值,該值唯一,缺點長度較大,支持數據庫有限,優點同uuid,跨數據庫,但是仍然需要訪問數據庫。注意:長度因數據庫不同而不同。

需要數據庫支持查詢uuid,生成時需要查詢數據庫,效率沒有uuid高,推薦使用uuid。

2.自然主鍵
assigned(用戶手動錄入)
由Java程序負責生成標識符,Hibernate不管理主鍵,用戶手動設置主鍵的值。如果不指定id元素的generator屬性,則默認使用該主鍵生成策略。


 

內容:

1 assigned
數據類型不限、保存前必須賦值

2 identity
數字,無需賦值

3 sequence
數字,無需賦值, 默認使hibernate_sequence這個序列,
也可以通過sequence/sequence_name參數賦值

4 increment
數字,無需賦值

5 uuid/uuid.hex (是由容器自動生成的一個32位的字符串,.hex代表的是十六進制)
32位的字符串,無需賦值,

6 native
等於identity+sequence

導入SessionFactoryUtils類

 1 public class SessionFactoryUtils {
 2     private static SessionFactory sessionFactory;
 3 //    存放當前會話
 4     private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
 5     static {
 6         Configuration cfg = new Configuration();
 7         Configuration configure = cfg.configure("/hibernate.cfg.xml");
 8         sessionFactory = configure.buildSessionFactory();
 9     }
10     
11     public static Session openSession() {
12         Session session = threadLocal.get();
13         if (null == session) {
14             session = sessionFactory.openSession();
15             threadLocal.set(session);
16         }
17         return session;
18     }
19 
20     public static void closeSession() {
21         Session session = threadLocal.get();
22         if (null != session) {
23             if (session.isOpen()) {
24                 session.close();
25             }
26             threadLocal.set(null);
27         }
28     }
29 
30     public static void main(String[] args) {
31         Session session = openSession();
32         System.out.println(session.isConnected());
33         closeSession();
34     }
35     
36 }

這個類在學習hibernate的過程中所用(整合SSH框架之前用)

作用:可以用來檢測所寫的映射文件是否正確;

然后創建好實體類和實體映射文件

學生類:

 1 public class Student implements Serializable  {
 2     
 3       private Integer sid;
 4       private String sname;
 5         public Integer getSid() {
 6             return sid;
 7         }
 8         public void setSid(Integer sid) {
 9             this.sid = sid;
10         }
11         public String getSname() {
12             return sname;
13         }
14         public void setSname(String sname) {
15             this.sname = sname;
16         }
17         @Override
18         public String toString() {
19             return "Worker [sid=" + sid + ", sname=" + sname + "]";
20         }
21 }

工人類:

 1 public class Worker implements Serializable{
 2        private String wid;
 3        private String wname;
 4     public String getWid() {
 5         return wid;
 6     }
 7     public void setWid(String wid) {
 8         this.wid = wid;
 9     }
10     public String getWname() {
11         return wname;
12     }
13     public void setWname(String wname) {
14         this.wname = wname;
15     }
16     @Override
17     public String toString() {
18         return "Worker [wid=" + wid + ", wname=" + wname + "]";
19     }
20        
21          
22     
23 }

兩個實體映射文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6     <class name="two.entity.Student" table="t_hibernate_student">
 7         <id name="sid" type="java.lang.Integer" column="sid">
 8             <!-- <generator class="assigned" />-->
 9             <!-- <generator class="identity" />  -->
10              <generator class="increment" />  
11             <!-- <generator class="sequence" /> -->
12             <!-- <generator class="sequence" > <param name="sequence_name">aaa</param> 
13                 </generator> -->
14             <!-- <generator class="com.javaxl.two.id.Myts" /> -->
15         </id>
16         <property name="sname" type="java.lang.String" column="sname">
17         </property>
18     </class>
19 </hibernate-mapping>
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6     <class name="two.entity.Worker" table="t_hibernate_work">
 7         <id name="wid" type="java.lang.String" column="wid">
 8             <!-- <generator class="uuid" /> -->
 9             <!-- <generator class="sequence" /> -->
10             <!-- <generator class="sequence" > <param name="sequence_name">aaa</param> 
11                 </generator> -->
12              <generator class="two.id.Myts" /> 
13         </id>
14 
15         <property name="wname" type="java.lang.String" column="wname">
16         </property>
17     </class>
18 </hibernate-mapping>

dao方法

 1 public class DemoDao {
 2     /**
 3      * 添加學生
 4      * @param stu
 5      * @return
 6      */
 7        public Serializable addStudent(Student stu) {
 8            Session session=SessionFactoryUtils.openSession();
 9            Transaction transaction=session.beginTransaction();
10            Serializable saveId=session.save(stu);
11            transaction.commit();
12            session.close();
13            return saveId;
14        }
15        /**
16         * 添加工人
17         * @param worker
18         * @return
19         */
20        public Serializable addWork(Worker worker) {
21            Session session=SessionFactoryUtils.openSession();
22            Transaction transaction=session.beginTransaction();
23            Serializable saveId=session.save(worker);
24            transaction.commit();
25            session.close();
26            return saveId;
27        }
28      
29        
30        
31 //       public static void teststudent(String[] args) {
32 //           
33 //           DemoDao dao=new DemoDao();
34 //           Student stu=new Student();
35 ////           stu.setSid(4);
36 //           stu.setSname("張三");
37 //           dao.addStudent(stu);
38 //           System.out.println(dao.addStudent(stu));
39 //    }
40        public static void main(String[] args) {
41            DemoDao dao=new DemoDao();
42            Worker worker=new Worker();
43            worker.setWname("啊哈哈哈");
44            System.out.println(dao.addWork(worker));
45     }
46        
47       
48 }

各位大佬們可以一一去試

最后一個自定義主鍵生成器

需要創建一個類來設置你需要變成的id格式

如下:

public class Myts implements IdentifierGenerator {

    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
        // TODO Auto-generated method stub
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return "shop_book_"+sdf.format(new Date());
    }

}

在dao方法類運行:

顯示如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM