zoukankan      html  css  js  c++  java
  • 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.GAprojectetchibernate.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

  • 相关阅读:
    sublime text 4 vim 插件配置
    ssh-keygen 的使用
    distribution transaction solution
    bilibili 大数据 视频下载 you-get
    Deepin 20.2.1 安装 MS SQL 2019 容器版本
    【转】使用Linux下Docker部署MSSQL并加载主机目录下的数据库
    【转】You Can Now Use OneDrive in Linux Natively Thanks to Insync
    dotnet 诊断工具安装命令
    Linux 使用 xrandr 设置屏幕分辨率
    【转】CentOS 7.9 2009 ISO 官方原版镜像下载
  • 原文地址:https://www.cnblogs.com/ShawnYang/p/6699805.html
Copyright © 2011-2022 走看看