hibernate_ID生成策略


increment:主鍵按數值順序遞增。此方式的實現機制為在當前應用實例中維持一個變量,以保存着當前的最大值,之后每次需要生成主鍵的時候將此值加1作為主鍵。這種方式可能產生的問題是:如果當前有多個實例訪問同一個數據庫,那么由於各個實例各自維護主鍵狀態,不同實例可能生成同樣的主鍵,從而造成主鍵重復異常。因此,如果同一數據庫有多個實例訪問,此方式必須避免使用

1)identity

    采用數據庫提供的主鍵生成機制。如DB2、SQL Server、MySQL中的主鍵生成機制。

2)sequence

    采用數據庫提供的sequence 機制生成主鍵。如Oralce 中的Sequence。

3)hilo

    hi/lo 算法實現的主鍵生成機制,需要額外的數據庫表保存主鍵生成歷史狀態。

4)seqhilo

    與hilo 類似,通過hi/lo 算法實現的主鍵生成機制,只是主鍵歷史狀態保存在Sequence中,適用於支持Sequence的數據庫,如Oracle。

5)uuid.hex

    由Hibernate基於128 位唯一值產生算法生成16 進制數值(編碼后以長度32 的字符串表示)作為主鍵。(跨數據庫)

6)uuid.hex

    Hibernate基於128 位唯一值產生算法生成16 進制數值(編碼后以長度32 的字符串表示)作為主鍵。(跨數據庫)

7)guid

    很少用;

8)native

    根據數據庫選擇自動遞增算法,常用;(跨數據庫)

9)assigned

    主鍵由外部程序負責生成,無需hibernate參與

10)select

    很少用;

11)foreign

    使用外部表的字段作為主鍵。

12)sequence-identity 很少用;

13)increment

    主鍵按數值順序遞增。此方式的實現機制為在當前應用實例中維持一個變量,以保存着當前的最大值,之后每次需要生成主鍵的時候將此值加1作為主鍵。這種方式可能產生的問題是:如果當前有多個實例訪問同一個數據庫,那么由於各個實例各自維護主鍵狀態,不同實例可能生成同樣的主鍵,從而造成主鍵重復異常。因此,如果同一數據庫有多個實例訪問,此方式必須避免使用。

  一般而言,利用uuid.hex方式生成主鍵將提供最好的性能和數據庫平台適應性。

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

  hibernate 的說明如下:

    不過值得注意的是,一些數據庫提供的主鍵生成機制在效率上未必最佳,大量並發insert數據時可能會引起表之間的互鎖。數據庫提供的主鍵生成機制,往往是通過在一個內部表中保存當前主鍵狀態(如對於自增型主鍵而言,此內部表中就維護着當前的最大值和遞增量),之后每次插入數據會讀取這個最大值,然后加上遞增量作為新記錄的主鍵,之后再把這個新的最大值更新回內部表中,這樣,一次Insert操作可能導致數據庫內部多次表讀寫操作,同時伴隨的還有數據的加鎖解鎖操作,這對性能產生了較大影響。因此,對於並發Insert要求較高的系統,推薦采用uuid.hex 作為主鍵生成機制。

路徑:hibernate-distribution-3.3.2.GA/documentation/manual/zh-CN/html_single/index.html#mapping-declaration-id

截圖:

uuid XML 配置:

1       <id name="id" column="id">
2             <generator class="uuid"/>
3         </id>

對應的JavaBean用String類型:

1     private String id;
2     public String getId() {
3         return id;
4     }
5 
6     public void setId(String id) {
7         this.id = id;
8     }

native XML 配置:

        <id name="id" column="id">
            <generator class="native"/>
        </id>

對應的JavaBean用Integer/int類型:

1     private Integer id;
2     public Integer getId() {
3         return id;
4     }
5 
6     public void setId(Integer id) {
7         this.id = id;
8     }

用 MySQL 數據庫,hibernate自動生成的建_student表的語句:

連接Oracle數據庫進行測試:

1、重新在 hibernate.cfg.xml文件中修改Oracle的連接配置,具體配置驅動、url、username、password的配置參考:

hibernate-distribution-3.3.2.GA\project\etc\hibernate.properties

2、java bean的屬性配置要符合oracle表和字段的命名規范;

3、ID 配置:

  XML 的跟上面的一樣;

  注解:默認就是AUTO(相當於native),可以不用寫,此時ID生成的sequence是hibernate_sequence;

       還有 IDENTITY(只能用在MySQL和SQL Server等支持IDENTITY的數據庫中,Oracle就用不了)SEQUENCETABLE

  @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
    public Integer getId() {
        return id;
    }

3.1、如果要為 model ID 指定確定的sequence,而不是去用默認的 hibernate_sequence,配置如下:

  注解:

    model頭:name 表示這個sequence生成器的名字,sequenceName 是指明序列在數據庫中的名字

@Entity
@SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")

    ID上的配置:

    

  @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="teacherSEQ")
    public Integer getId() {
        return id;
    }

  XML:在 hibernate.cfg.xml 中的配置

 1 <hibernate-mapping>
 2     <class name="..." table="..." schema="...">
 3         <id name="userId" type="java.lang.Integer">
 4             <column name="USER_ID" precision="9" scale="0" />
 5             <generator class="sequence">
 6             <param name="sequence">Student_SEQ</param>
 7             </generator>
 8         </id>
 9          <property ... />
10     </class>
11 </hibernate-mapping>

  3.2、復雜一點的主鍵生成器——TableGenerator    

 1     @javax.persistence.TableGenerator(
 2         name="Teacher_GEN",//生成器名
 3         table="GENERATOR_TABLE",//表名
 4         pkColumnName = "pk_key",//第一個字段,key值
 5         valueColumnName = "pk_value",//第二個字段,value值
 6         pkColumnValue="Teacher",//一條記錄的第一個字段
 7         allocationSize=1//增量
 8     )
 9     @Id
10     @GeneratedValue(strategy=GenerationType.TABLE,generator="Teacher_GEN")
11     public Integer getId() {
12         return id;
13     }

初次使用該生成器,生成器找到對應的記錄,返回value值1,同時value加上對應的增量。

  3.3 聯合主鍵

    XML:一個表中的兩個字段做主鍵,例子中取Student中的id、name做主鍵,創建一個StudentPK做主鍵類,在Student中配置好聯合主鍵

Student

package com.bjsxt.hibernate;

public class Student {
    
    private StudentPK pk;

    private Integer age;

    public StudentPK getPk() {
        return pk;
    }

    public void setPk(StudentPK pk) {
        this.pk = pk;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    
}

StudentPK 需要實現Serializable接口,重寫hashCode()和equals()方法

 1 package com.bjsxt.hibernate;
 2 
 3 import java.io.Serializable;
 4 
 5 public class StudentPK implements Serializable{
 6     
 7     private static final long serialVersionUID = -7950018142709463675L;
 8 
 9     private Integer id;
10     
11     private String name;
12 
13     public Integer getId() {
14         return id;
15     }
16 
17     public void setId(Integer id) {
18         this.id = id;
19     }
20 
21     public String getName() {
22         return name;
23     }
24 
25     public void setName(String name) {
26         this.name = name;
27     }
28     
29     @Override
30     public boolean equals(Object o) {
31         if(o instanceof StudentPK){
32             StudentPK pk = (StudentPK)o;
33             if(this.id == pk.getId() && this.name.equals(pk.getName())){
34                 return true;
35             }
36         }
37         return false;
38     }
39     
40     @Override
41     public int hashCode() {
42         return this.name.hashCode();
43     }
44 }

Student.hbm.xml

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 5 
 6 <hibernate-mapping package="com.bjsxt.hibernate">
 7     <class name="Student" table="student">
 8         <composite-id name="pk" class="com.bjsxt.hibernate.StudentPK">
 9             <key-property name="id" />
10             <key-property name="name" />
11         </composite-id>
12         <property .../>
13     </class>
14 </hibernate-mapping>

插入操作:

1   @Test
2     public void testStudentSave(){
3         StudentPK pk = new StudentPK();
4         pk.setId(1);
5         pk.setName("zhangsan");
6         Student s = new Student();
7         s.setPk(pk);
8         ...
9     }

    Annotation:

      第一種方法:將組件類注解為@Embeddable,並將組件的屬性注解為@Id;

      第二種方法:將組件的屬性注解為@EmbeddedId;

      第三種方法:將類注解為@IdClass,並將該實體中所有屬於主鍵的屬性都注解為@Id;

      3種方法的主鍵類同樣要需要實現Serializable接口,重寫hashCode()和equals()方法。

        第一種方法例子:

TeacherPK

 1 package com.bjsxt.hibernate;
 2 
 3 import java.io.Serializable;
 4 
 5 @Embeddable
 6 public class TeacherPK implements Serializable{
 7     
 8     private static final long serialVersionUID = -3972276136768456123L;
 9 
10     private Integer id;
11     
12     private String name;
13 
14     public Integer getId() {
15         return id;
16     }
17 
18     public void setId(Integer id) {
19         this.id = id;
20     }
21 
22     public String getName() {
23         return name;
24     }
25 
26     public void setName(String name) {
27         this.name = name;
28     }
29     
30     @Override
31     public boolean equals(Object o) {
32         if(o instanceof StudentPK){
33             StudentPK pk = (StudentPK)o;
34             if(this.id == pk.getId() && this.name.equals(pk.getName())){
35                 return true;
36             }
37         }
38         return false;
39     }
40     
41     @Override
42     public int hashCode() {
43         return this.name.hashCode();
44     }
45     
46 }
View Code

Teacher

 1 package com.bjsxt.hibernate;
 2 
 3 import java.util.Date;
 4 
 5 import javax.persistence.EmbeddedId;
 6 import javax.persistence.Entity;
 7 import javax.persistence.EnumType;
 8 import javax.persistence.Enumerated;
 9 import javax.persistence.GeneratedValue;
10 import javax.persistence.GenerationType;
11 import javax.persistence.Id;
12 import javax.persistence.IdClass;
13 import javax.persistence.SequenceGenerator;
14 import javax.persistence.Temporal;
15 import javax.persistence.TemporalType;
16 
17 @javax.persistence.TableGenerator(
18         name="Teacher_GEN",//生成器名
19         table="GENERATOR_TABLE",//表名
20         pkColumnName = "pk_key",//第一個字段,key值
21         valueColumnName = "pk_value",//第二個字段,value值
22         pkColumnValue="Teacher",//記錄值
23         allocationSize=1//增量
24     )
25 
26 @Entity
27 @SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")
28 public class Teacher {
29     private TeacherPK pk;
30     
31     private String title;
32     
33     private Date birthday;
34     
35     private ZhiCheng zhicheng;
36 
37     public String getTitle() {
38         return title;
39     }
40 
41     @Id
42     public TeacherPK getPk() {
43         return pk;
44     }
45 
46     public void setPk(TeacherPK pk) {
47         this.pk = pk;
48     }
49 
50     public void setTitle(String title) {
51         this.title = title;
52     }
53 
54     @Temporal(TemporalType.DATE)
55     public Date getBirthday() {
56         return birthday;
57     }
58 
59     public void setBirthday(Date birthday) {
60         this.birthday = birthday;
61     }
62 
63     @Enumerated(value=EnumType.STRING)
64     public ZhiCheng getZhicheng() {
65         return zhicheng;
66     }
67 
68     public void setZhicheng(ZhiCheng zhicheng) {
69         this.zhicheng = zhicheng;
70     }
71     
72 }
View Code

      第二種方法例子:

TeacherPK

 1 package com.bjsxt.hibernate;
 2 
 3 import java.io.Serializable;
 4 
 5 public class TeacherPK implements Serializable{
 6     
 7     private static final long serialVersionUID = -3972276136768456123L;
 8 
 9     private Integer id;
10     
11     private String name;
12 
13     public Integer getId() {
14         return id;
15     }
16 
17     public void setId(Integer id) {
18         this.id = id;
19     }
20 
21     public String getName() {
22         return name;
23     }
24 
25     public void setName(String name) {
26         this.name = name;
27     }
28     
29     @Override
30     public boolean equals(Object o) {
31         if(o instanceof StudentPK){
32             StudentPK pk = (StudentPK)o;
33             if(this.id == pk.getId() && this.name.equals(pk.getName())){
34                 return true;
35             }
36         }
37         return false;
38     }
39     
40     @Override
41     public int hashCode() {
42         return this.name.hashCode();
43     }
44     
45 }
View Code

Teacher

 1 package com.bjsxt.hibernate;
 2 
 3 import java.util.Date;
 4 
 5 import javax.persistence.EmbeddedId;
 6 import javax.persistence.Entity;
 7 import javax.persistence.EnumType;
 8 import javax.persistence.Enumerated;
 9 import javax.persistence.GeneratedValue;
10 import javax.persistence.GenerationType;
11 import javax.persistence.Id;
12 import javax.persistence.IdClass;
13 import javax.persistence.SequenceGenerator;
14 import javax.persistence.Temporal;
15 import javax.persistence.TemporalType;
16 
17 @javax.persistence.TableGenerator(
18         name="Teacher_GEN",//生成器名
19         table="GENERATOR_TABLE",//表名
20         pkColumnName = "pk_key",//第一個字段,key值
21         valueColumnName = "pk_value",//第二個字段,value值
22         pkColumnValue="Teacher",//記錄值
23         allocationSize=1//增量
24     )
25 
26 @Entity
27 @SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")
28 public class Teacher {
29     private TeacherPK pk;
30     
31     private Integer id;
32     
33     private String name;
34     
35     private String title;
36     
37     private Date birthday;
38     
39     private ZhiCheng zhicheng;    
40 
41     public void setName(String name) {
42         this.name = name;
43     }
44 
45     public String getTitle() {
46         return title;
47     }
48 
49 
50     @EmbeddedId
51     public TeacherPK getPk() {
52         return pk;
53     }
54 
55     public void setPk(TeacherPK pk) {
56         this.pk = pk;
57     }
58 
59     public void setTitle(String title) {
60         this.title = title;
61     }
62 
63     @Temporal(TemporalType.DATE)
64     public Date getBirthday() {
65         return birthday;
66     }
67 
68     public void setBirthday(Date birthday) {
69         this.birthday = birthday;
70     }
71 
72     @Enumerated(value=EnumType.STRING)
73     public ZhiCheng getZhicheng() {
74         return zhicheng;
75     }
76 
77     public void setZhicheng(ZhiCheng zhicheng) {
78         this.zhicheng = zhicheng;
79     }
80     
81 }
View Code

    第三種方法例子:

TeacherPK

 1 package com.bjsxt.hibernate;
 2 
 3 import java.io.Serializable;
 4 
 5 public class TeacherPK implements Serializable{
 6     
 7     private static final long serialVersionUID = -3972276136768456123L;
 8 
 9     private Integer id;
10     
11     private String name;
12 
13     public Integer getId() {
14         return id;
15     }
16 
17     public void setId(Integer id) {
18         this.id = id;
19     }
20 
21     public String getName() {
22         return name;
23     }
24 
25     public void setName(String name) {
26         this.name = name;
27     }
28     
29     @Override
30     public boolean equals(Object o) {
31         if(o instanceof StudentPK){
32             StudentPK pk = (StudentPK)o;
33             if(this.id == pk.getId() && this.name.equals(pk.getName())){
34                 return true;
35             }
36         }
37         return false;
38     }
39     
40     @Override
41     public int hashCode() {
42         return this.name.hashCode();
43     }
44     
45 }
View Code

Teacher

 1 package com.bjsxt.hibernate;
 2 
 3 import java.util.Date;
 4 
 5 import javax.persistence.EmbeddedId;
 6 import javax.persistence.Entity;
 7 import javax.persistence.EnumType;
 8 import javax.persistence.Enumerated;
 9 import javax.persistence.GeneratedValue;
10 import javax.persistence.GenerationType;
11 import javax.persistence.Id;
12 import javax.persistence.IdClass;
13 import javax.persistence.SequenceGenerator;
14 import javax.persistence.Temporal;
15 import javax.persistence.TemporalType;
16 
17 @javax.persistence.TableGenerator(
18         name="Teacher_GEN",//生成器名
19         table="GENERATOR_TABLE",//表名
20         pkColumnName = "pk_key",//第一個字段,key值
21         valueColumnName = "pk_value",//第二個字段,value值
22         pkColumnValue="Teacher",//記錄值
23         allocationSize=1//增量
24     )
25 
26 @Entity
27 @SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")
28 @IdClass(StudentPK.class)
29 public class Teacher {
30     private Integer id;
31     
32     private String name;
33     
34     private String title;
35     
36     private Date birthday;
37     
38     private ZhiCheng zhicheng;
39 
40     @Id
41     public Integer getId() {
42         return id;
43     }
44 
45     public void setId(Integer id) {
46         this.id = id;
47     }
48 
49     @Id
50     public String getName() {
51         return name;
52     }
53 
54     public void setName(String name) {
55         this.name = name;
56     }
57 
58     public String getTitle() {
59         return title;
60     }
61 
62     public void setTitle(String title) {
63         this.title = title;
64     }
65 
66     @Temporal(TemporalType.DATE)
67     public Date getBirthday() {
68         return birthday;
69     }
70 
71     public void setBirthday(Date birthday) {
72         this.birthday = birthday;
73     }
74 
75     @Enumerated(value=EnumType.STRING)
76     public ZhiCheng getZhicheng() {
77         return zhicheng;
78     }
79 
80     public void setZhicheng(ZhiCheng zhicheng) {
81         this.zhicheng = zhicheng;
82     }
83     
84 }
View Code

鏈接: http://pan.baidu.com/s/1qYayZk4 密碼: ta5c

所需jar包鏈接: http://pan.baidu.com/s/1hr35oVU 密碼: yhsf


免責聲明!

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



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