(2)id:单个属性(AUTO、Table)联合主键三种实现方式
一、单个主键
@Entity
//从这个包(javax.persistence.Entity)可以看出,是个标准,不依赖于hibernate
//@Table(name="_Teacher") //当model类和数据库的表名,不一致时,应该在这里指定。在这里类名为:teacher,表名是:_Teacher
//生成一个表名是GENERATOR_TABLE的表,有两个字段pk_key、pk_value。 pkColumnValue是一条记录pk_key
//简单理解:这个表存表名和下一次的id号
//下面的getId:处写@GeneratedValue(strategy=GenerationType.TABLE,generator="teacher_GEN" )
//这是跨数据库平台【但是这很少用】
@javax.persistence.TableGenerator(
name="teacher_GEN",
table="GENERATOR_TABLE",
pkColumnName = "pk_key",
valueColumnName = "pk_value",
pkColumnValue="teacher",
allocationSize=1
)
/*
* 这个演示单个主键
*/
public class teacher {
private int id;
private String name;
private int age;
private String sex;
private Date birthDate;
private ZhiCheng zhicheng;
@Id //必须加在getId上面
//@GeneratedValue(strategy=GenerationType.IDENTITY)//这样指定,只能在mysql或者sql service
// @GeneratedValue(strategy=GenerationType.SEQUENCE)//这样指定,能在oracle中运用
/*@GeneratedValue 在只这样写,而没有()里面的内容时
* 【常用】
* auto:可以是identity column类型或者sequence类型、table类型,取决于底层数据库 ,不用人为判断
* auto :在mysql、sql service中用auto_increment(identity) 在oracle中用sequence
*/
@GeneratedValue(strategy=GenerationType.TABLE,generator="teacher_GEN" )
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
1.@Id可以将实体bean中的某个属性定义为标识符,该属性的值可以通过应用自身进行设置,也可以通过hibernate生成(推荐),如何让hibernate生成呢?使用@GeneratedValue注解可以定义该标识符的生产策略:
①AUTO:依据底层的数据库自动选择生成策略。在mysql 、sql service中用auto_increment(identity)在oracle中用sequence。若只写@GeneratedValue,即默认情况,则是auto ,具体来说是identity
②TABLE 可以让多个表共享一个生成策略,
//定义在类外
@javax.persistence.TableGenerator(
name="teacher_GEN",//在类中生成器的名称
table="GENERATOR_TABLE",//生成器表名
pkColumnName = "pk_key",//列名
valueColumnName = "pk_value",//列名
pkColumnValue="teacher",// pkColumnName对应的值
allocationSize=1
)
@Id
@GeneratedValue(strategy=GenerationType.TABLE,generator="teacher_GEN")
public int getId() {
return id;
}
GENERATOR_TABLE表
-------------------------
pk_key | pk_value
------------------------------
teacher | 下一次插入的键值
------------------------
这是类级生成器,类级别生成器杂类外是不可见的。若要多个类是同一个表级生成策略,则应该在每个类中均要写
二、联合主键
一般要把联合主键放在单独的类中,并且该类必须实现serializable,必须复写hashcode、equals方法
用注解的方式实现组合主键,只是省略了配置文件,还是要实现serializable、复写hashcode、equals方法。
有三种实现方式:
①组件类注解为@Embeddable,并将组件的属性注解为@Id【注意是将引用该类的类中注解@Id】
②将组件的属性注解为@EmbeddedId 【简单方便】
③将类注解为@IdClass ,并将该实体中所有主键的属性都注解为@Id
这种方式中,teacher中仍然有主键属性,详情看:com.model1.teacher3
但是teacher1PK必须得写
//@Embeddable//方式一
public class teacher1PK implements 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 int hashCode() {
return id*10+name.hashCode();
}
@Override
public boolean equals(Object obj) {
if(obj instanceof teacher1PK){
teacher1PK pk=(teacher1PK) obj;
if(pk.id==this.id&&pk.name==this.name)
{
return false;
}
}
return true;
}
}
teacher1
@Entity
public class teacher1 {
private teacher1PK pk;
private int age;
private String sex;
private Date birthDate;
//@Id方式一
//@EmbeddedId//方式二
public teacher1PK getPk() {
return pk;
}
public void setPk(teacher1PK pk) {
this.pk = pk;
}
}
teacher3类
@Entity
@IdClass(value = teacher1PK.class)//指明对应的主键类
public class teacher3 {
private int id;
private String name;
private int age;
private String sex;
private Date birthDate;
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="_name",
length=10,nullable=false)//当类中属性名和数据库中字段名不一致时,通过这个注解,就能实现类中字段name到数据库字段_name的映射。但要注意要写在get方法上面
//若对数据库中的属性字段有限制,可以在@Column中设定
@Id
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}