一、生成策略有:
1.increment
用于为long,short或者int类型生成唯一标识。
只有在没有其他进程往同一张表中插入数据时才能使用。
2.identity(常用)
对DB2,MySQL,MS SQL Server,Sybase和HypersonicSQL的内置标识字段提供支持
返回的标识符是long,short或者int类型。
即mysql中的auto_increment
3.sequence(常用)
在DB2,PostgreSQL,Oracle,SAP DB,McKoi中使用序列,而在Interbase中使用生成器
返回的标识符是long,short或者int类型。
4.hilo(不重要)
使用一个高低位算法高效生成long,short或者int类型的标识符
5.seqhilo(不重要)
6.uuid(较常用,适合于跨数据库平台的项目)
使用128位的uuid算法来生成string类型的id
全局统一的identity,理论上不可能产生同样的值
<id name="id">
<generator class="uuid"></generator>
</id>
private String id;
7.guid
相对于uuid来说范围较小,不是全局的
8.native(常用,适合于跨数据库平台的项目)
让数据库自动选择是identity,sequence还是hilo
<id name="id">
<generator class="native"></generator>
</id>
private int id;
9.assigned
10.select
从表中去取
11.foreign
外键
12.sequence-identity
二、生成的方式
1.xml生成id
a.使用generator标签
b.常用四个:native identity sequence uuid
2.annotation生成id GeneratedValue四种取值
a.默认采用AUTO,相当于native,
@Id
@GeneratedValue
对mysql使用auto_increment,对oracle使用hibernate_sequence(名称固定)
b.TABLE 使用表保存id值(很少用,了解即可)
@Entity
@javax.persistence.TableGenerator(
name="Teacher_GEN",//生成器名称
table="GENERSTOR_TABLE",//表名
pkColumnName="pk_key",//主键列名
valueColumnName="pk_value",//值列名
pkColumnValue="Teacher",//一条记录的key列值是Teacher
allocationSize=1//每次递增的值
)
//实际上这张表保存的是其他每张表要取的下一个id值
@Id
@GeneratedValue(strategy=GenerationType.TABLE,generator="Teacher_GEN")
优点:跨数据库平台的时候使用较为方便,AUTO虽然也可以跨平台,但是不同的平台生成id的方式不同
c.IDENTITY
@GeneratedValue(strategy=GenerationType.IDENTITY)
d.SEQUENCE
@GeneratedValue(strategy=GenerationType.SEQUENCE)
一般多表共用一个sequence,解决办法:
在类名上面添加注解
@Entity
@SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")//第一个是生成器的名字,第二个是序列名称
在get方法上添加注解
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="teacherSEQ")
三、联合主键
1.xml方式
需要单独设计一个类作为主键类,而且必须重写equals,hashcode和实现可序列化接口
(重写是为了保证唯一性;序列化是因为需要存储到硬盘上或者通过网络传输)
此处序列化原因:a.多台服务器集群的时候需要通过网络传输
b.内存不够,使用一部分硬盘作为虚拟内存的时候需要写在硬盘上
public class StudentPK implements java.io.Serializable
{
private int id;
private String 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();
}
}
<composite-id name="pk" class="">
<key-property name="id"></key-property>
<key-property name="name"></key-property>
</composite-id>
2.annotation方式
a.将组件类注解为@Embeddable(嵌入),并将组件的属性注解为@Id
@Embeddable
public class TeacherPK implements java.io.Serializable
{
}
public class Teacher
{
@Id
public TeacherPK getPk(){
return pk;
}
}
b.将组件的属性注解为@EmbeddedId(最常用)
public class Teacher
{
@EmbeddedId
public TeacherPK getPk(){
return pk;
}
}
c.将类注解为@IdClass(较常用),并将该实体中所有属于主键的属性都注解为@Id
@IdClass(value="TeacherPK.class")//需要主键对象才能load,所以TeacherPK这个类还是需要的
public class Teacher
{
@Id
public int getId(){
return id;
}
@Id
public String getName(){
return name;
}
}