码迷,mamicode.com
首页 > Web开发 > 详细

hibernate(四)ID生成策略

时间:2015-12-14 23:03:55      阅读:307      评论:0      收藏:0      [点我收藏+]

标签:

一、ID生成策略配置

1、ID生成方式在xml中配置方式:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.orlion.hibernate.model">
    <class name="Student" table="student"><!-- 如果表名与类名相同可以不用写table属性 -->
        <!-- 用id映射主键 -->
        <id name="id"> <!-- 列名相同可以不指定column属性 -->
            <generator class="native"></generator><!-- 在这里设置id生成方式 -->
        </id>
        
        <property name="name" column="name"></property>
        <property name="age"></property>
    </class>
</hibernate-mapping>

2、ID用注解配置:

在ID注解下添加注解@generatedValue,只有四种方式,默认的策略是auto

配置方式:@genetatedValue(strategy=GenerationType.AUTO)

(1)AUTO - 相当于采用xml中native方式

(2)TABLE - 使用表保存id值

 

(3)IDENTITY - identity column

(4)SEQUENCE - sequence

在类名上添加注解@SequenceGenerator(name="teacherSEQ" , sequenceName="teacherSEQ_DB");定义sequence生成器,name属性指定的是生成器名字,sequenceName指定的是sequence名字

在getId()方法上添加注解@genetatoedValue(strategy=GenerationType.SEQUENCE , generator="teacherSEQ")表示采用sequence生成策略,采用生成器是teacherSEQ

 

二、ID主要生成策略

hibernate中id生成主要方式有:

(1)native:根据不同的数据库采用不同的ID生成方式,例如:在SQL Server中采用identity; 在MySQL中采用auto_increment; 在ORACLE中就会采用sequence。

(2)uuid:原理是使用128位的uuid算法产生主键,从而能够确保网络环境下的一致性。使用此生成策略时,实体类的主键是String类型的,映射成表中字段为varchar。适用所有数据库。

(3)identity:这种策略在采用SQL Server时,相当于SQL Server的identity关键字。

(4)sequence:在 Oracle中使用序列(sequence)。返回的标识符是long, short或者 int类型的。

 

三、联合主键

1、xml文件方式配置联合主键

单独建一个类作为主键类,以Student类为例,假设student有两个主键id和name,那么可以建一个主键类StudentPK,主键类中包含两个属性即student的两个主键,而且要实现Serializable接口,覆盖equals和hashCode方法:

package cn.orlion.hibernate.model;
// 实现Serializable接口
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;
    }
    // 覆盖equals方法
    public boolean equals(Object o){
        
        if (o instanceof StudentPK) {
            StudentPK pk = (StudentPK)o;
            return this.id == pk.getId() && this.name.equals(((StudentPK) o).getName());
        }
        
        return false;
    }
    // 覆盖hashCode方法
    public int hashCode(){
        return this.name.hashCode();
    }
}

 

这时Student应该去掉int和name属性然后加上StudentPK属性,如下:

package cn.orlion.hibernate.model;

public class Student {
    
    private StudentPK spk;
    
//    private int id;
//    
//    private String name;
    
    public StudentPK getSpk() {
        return spk;
    }

    public void setSpk(StudentPK spk) {
        this.spk = spk;
    }

    private int age;

//    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;
    }
}

然后修改配置文件为:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.orlion.hibernate.model">
    <class name="Student" table="student"><!-- 如果表名与类名相同可以不用写table属性 -->
  
     <!-- 在这里修改主键配置 --> <composite-id name="spk" class="cn.orlion.hibernate.model.StudentPK"> <key-property name="id"></key-property> <key-property name="name"></key-property> </composite-id> <property name="age"></property> </class> </hibernate-mapping>

 

这样往数据库中插入一条数据就应该下new一个StudentPK,然后再new一个Student对象:

StudentPK spk = new StudentPK();
        spk.setId(1);
        spk.setName("test1");
        Student t = new Student();
        t.setSpk(spk);
        // t.setName("test1");
        t.setAge(1);
        
        Session session = sf.openSession();
        
        session.beginTransaction();
        session.save(t);
        session.getTransaction().commit();
        
        session.close();

 

2、注解方式配置联合主键

共有三种方式:

(1)将组件类注解为@Embeddable,并将组件的属性注解为@ID

具体过程:

创建组件类:TeacherPK(实现serializable接口,覆盖equals和hashCode方法)

package cn.orlion.hibernate.model;

import javax.persistence.Embeddable;

@Embeddable
public class TeacherPK 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;
    }
    // 覆盖equals方法
    public boolean equals(Object o){
            
        if (o instanceof StudentPK) {
            StudentPK pk = (StudentPK)o;
            return this.id == pk.getId() && this.name.equals(((StudentPK) o).getName());
        }
            
        return false;
    }
    // 覆盖hashCode方法
    public int hashCode(){
        return this.name.hashCode();
    }
}

然后Teacher类:(注释掉id和name属性,添加TeacherPK属性,并加上注解@Id)

package cn.orlion.hibernate.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Teacher{
    
    private TeacherPK tpk;

//    private int id;
//    
//    private String name;
    @Id
    public TeacherPK getTpk() {
        return tpk;
    }

    public void setTpk(TeacherPK tpk) {
        this.tpk = tpk;
    }

    private String title;
//    @Id
//    @GeneratedValue(strategy = GenerationType.AUTO)
//    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 getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

保存teacher对象的时候:

TeacherPK tpk = new TeacherPK();
        tpk.setId(1);
        tpk.setName("test1");
        Teacher t = new Teacher();
        t.setTpk(tpk);
//        t.setName("test2");
        t.setTitle("title1");
        
        Session session = sf.openSession();
        
        session.beginTransaction();
        session.save(t);
        session.getTransaction().commit();
        
        session.close();

可以看到建表:

技术分享

(2)在组件属性添加注解@EmbeddedId

具体为:去掉TeacherPK类上的注解@Embeddable,然后在Teacher类中的getTpk()方法上的注解由@Id改为@EmbeddedId

(3)将类注解为@IdClass,并将该实体中所有属于主键的属性都注解为@Id

具体:

修改Teacher类为:(注:id生成策略设为AUTO的时候会在TeacherPK的setId()方法上抛出一个异常IllegalArgumentException,"POST_INSERT_INDICATOR")

package cn.orlion.hibernate.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;

@Entity
@IdClass(TeacherPK.class)
public class Teacher{

    private int id;
    
    private String name;
    
    private String title;
    @Id
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    @Id
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

TeacherPK:

package cn.orlion.hibernate.model;

public class TeacherPK 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;
    }
    // 覆盖equals方法
    public boolean equals(Object o){
            
        if (o instanceof StudentPK) {
            StudentPK pk = (StudentPK)o;
            return this.id == pk.getId() && this.name.equals(((StudentPK) o).getName());
        }
            
        return false;
    }
    // 覆盖hashCode方法
    public int hashCode(){
        return this.name.hashCode();
    }
}

保存Teacher对象的时候:

Teacher t = new Teacher();
        t.setName("test1");
        t.setId(1);
        t.setTitle("title1");
        
        Session session = sf.openSession();
        
        session.beginTransaction();
        session.save(t);
        session.getTransaction().commit();
        
        session.close();

 

hibernate(四)ID生成策略

标签:

原文地址:http://www.cnblogs.com/orlion/p/5046702.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!