Hibernate 再接触 ID生成策略

Xml 方法

在student.hbm.xml中

<generator class="uuid"></generator>

取值如下

1、identity:用于MySql数据库。特点:递增

 


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

 

注:对于MySql数据库使用递增序列时需要在建表时对主键指定为auto_increment属性。

2、sequence:用于Oracle数据库

 

 
  1. <id name="id" column="id">  
  2. <generator class="sequence">  
  3. <param name="sequence">序列名</param>  
  4. </generator>  
  5. </id>   

 

3、native:跨数据库时使用,由底层方言产生。 
Default.sequence为hibernate_sequence

 


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

 

注:使用native时Hibernate默认会去查找Oracle中的hibernate_sequence序列。 
如果Oracle中没有该序列,连Oracle数据库时会报错。

4、hilo:通过高低位合成id,先建表hi_value,再建列next_value。必须要有初始值。


 

 
  1. <id name="id" column="id">  
  2. <generator class="hilo">  
  3. <param name="table">high_val</param>  
  4. <param name="column">nextval</param>  
  5. <param name="max_lo">5</param>  
  6. </generator>  
  7. </id>    

 

5、sequencehilo:同过高低位合成id,建一个sequence序列,不用建表。

 


 
  1. <id name="id" column="id">  
  2. <generator class="hilo">  
  3. <param name="sequence">high_val_seq</param>  
  4. <param name="max_lo">5</param>  
  5. </generator>  
  6. </id>   

 

6、assigned:用户自定义id;

 


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

 

7、foreign:用于一对一关系共享主健时,两id值一样。

本文讲解Hibernate中hbm的generator子元素的一些内置生成器的快捷名字。Generator子元素是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。

在*.hbm.xml必须声明的< generator>子元素是一个Java类的名字,用来为该持久化类的实例生成唯一的标识。

 


 
  1. <generator class="sequence"/>  

 

这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然,Hibernate提供了很多内置的实现。下面是Generator子元素的一些内置生成器的快捷名字:

Annotation方法

 

package com.easy;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class student {
    private int id;
    private String name;
    private int age;
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
}

JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO. 
TABLE:使用一个特定的数据库表格来保存主键。 
SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。 
IDENTITY:主键由数据库自动生成(主要是自动增长型) 
AUTO:主键由程序控制。 

Annotation更改sequence名称

在类前加

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

指定触发器名称

@GeneratedValue(strategy = GenerationType.SEQUENCE,generator ="teacherSEQ" )

使用表生成id

在类前加

@javax.persistence.TableGenerator(
        name="Teacher_GEN",
        table="GENERATOR_TABLE",
        pkColumnName = "pk_key",
        valueColumnName = "pk_value",
        pkColumnValue="Teacher",
        allocationSize=1
    )
@GeneratedValue(strategy = GenerationType.table,generator ="teacherSEQ" )

联合主键

例如用id name作为联合主键

Xml方式

新建一个联合主键类 然后重写equals 和hashcode方法 保证在内存中寻找主键

package com.bjsxt.hibernate;

public class StudentPK implements java.io.Serializable{
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    @Override
    public boolean equals(Object o) {
        if(o instanceof StudentPK) {
            StudentPK pk = (StudentPK)o;
            if(this.id == pk.getId() && this.name.equals(pk.getName())) {
                return true;
            }
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        return this.name.hashCode();
    }
}

Student.java

package com.bjsxt.hibernate;

import javax.persistence.Id;

public class Student {
    

   private StudentPK pk;

    
    private int age;
    private String sex;
    private boolean good;
    public boolean isGood() {
        return good;
    }
    public void setGood(boolean good) {
        this.good = good;
    }
    /*public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }*/
/*    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }*/
    /*public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }*/
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public StudentPK getPk() {
        return pk;
    }
    public void setPk(StudentPK pk) {
        this.pk = pk;
    }
    
    
}

Test

@Test
    public void testStudentSave() {
        Student s = new Student();
    StudentPK pk = new StudentPK();
        
        pk.setId(1);
        pk.setName("zhangsan");
        
        s.setPk(pk);
        s.setAge(8);
        
        
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        session.save(s);
        session.getTransaction().commit();
    }
    

2.annotation版本

有3种方式

第一种

在主键类上加

@Embeddable

然后在类生成

private TeacherPK pk; 并生成get set方法

然后在get上写@id

第二种

生成逐渐类后

private TeacherPK pk; 并生成get set方法 

然后再get上写

@EmbeddedId

第三种

直接在getid 和getname上写@id

在类前加注释

@IdClass(TeacherPK.class)

 

posted @ 2018-09-04 23:54  橘柑之味  阅读(103)  评论(0编辑  收藏  举报