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

posted @ 2017-04-12 16:23  流年如水烟雨随风  阅读(4036)  评论(0编辑  收藏  举报