Hibernate 官方文档中,主键生成策略有十几种之多,但是在实际开发的过程中,常用的有四种(auto,identity,sequence,select).,其他的策略了解即可,使用到的时候再查也是可以的。
1.策略简介
auto 让hibernate自动选择产生主键的方式。hibernate会根据使用的数据库来判定使用identity或是sequence。
identity 对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。 返回的标识符是long, short 或者int类型的。 sequence 在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。 select 通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。 这种方式一般建立一张专门生成id的表,然后让hibernate帮我们管理这张表。这种方式虽然用的并不多,但是可以通过一张表就可以产生N个不同主键供系统使用(每一行数据都是一个主键)。
2.ID策略实例应用(Annotation版本)
2.1auto
在实体类id添加@Id和@GeneratedValue(或是@GeneratedValue(strategy=GenerationType.AUTO)注意如果使用的是mysql的话,就使用identity自动增长的方式来生成主键,如果是Oracle的话,hibernate自动生成一个sequence,默认的名字为hibernate_sequence。
package com.founder.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Student {
private int id;
private String name;
@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;
}
}
2.2identity 对能够自动增长的数据库有效,对MySQL无效。
package com.founder.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Student {
private int id;
private String name;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
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;
}
}
2.3 使用sequence
package com.founder.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
@Entity
@SequenceGenerator(name="s1",sequenceName="h_s_1")
//SequenceGenerator的name是策略名,用来被@GeneratedValue的generator属性引用
//sequenceName是数据库侧生成的sequence名称。
public class Student {
private int id;
private String name;
@Id
//generator属性引用定义@SequenceGenerator定义的name
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="s1")
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;
}
}
2.4 Select 类型,最复杂,但用的不多。复杂点在于@TableGenerator的配置比较复杂(因为要新建一张表)
package com.founder.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.TableGenerator;
@Entity
@TableGenerator(name="g_t_1",
table="tablegen1",
pkColumnName="GEN_KEY",
valueColumnName="GEN_ID",
pkColumnValue="tg1")
//table表名
//pkColumnName key字段
//valueColumnName value字段
//pkColumnValue本实体类使用的数据,该行数据的特征为GEN_KEY字段等于tg1,GEN_ID 字段就是系统取的id,hibernate取一次将其加1.
public class Student {
private int id;
private String name;
@Id
//generator属性引用定义@SequenceGenerator定义的name
@GeneratedValue(strategy=GenerationType.TABLE,generator="g_t_1")
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;
}
}
数据库一侧产生了这样一张表
create table tablegen1 (
GEN_KEY varchar2(255),
GEN_ID number(10,0)
)
3.联合主键。Hibernate联合主键需要生成一个中间类(PK_Class),在真正的实体类中增加该PK_CKass的一个应用即可。