一、ID生成策略配置
1、ID生成方式在xml中配置方式:
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; }}
然后修改配置文件为:
这样往数据库中插入一条数据就应该下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;@Embeddablepublic 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;@Entitypublic 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();