1. hibernate的主键生成器:
在*.hbm.xml文件里定义generator元素,generator元素表示了一个主键生成器,它用来为持久化类实例生成唯一的标识
2、表中主键分类:
(1)自然主键:建表的时候,使用对象中本身的属性作为表的主键。
(2)代理主键:没有使用对象中的自身的属性作为表中的主键,使用和对象不相关的属性作为主键。
注:在建表的时候,建议使用代理主键,自然主键有可能会参与到业务逻辑中,有可能出现重复或者有的时候需要修改,主键不能修改,因此自然主键就不能使用了。
3、主键生成策略:
主键不应该由用户自己输入,而是由程序生成。
(1)increment(数字,无需赋值):自动增长,使用的是Hibernate中提供的自动增长机制,适应于short,int,Long。Hibernate底层使用查询一下表中主键的最大值。select max(cust id ) from customer,然后将id+1作为当前的主键。
特点:跨数据库,不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于集群环境。
(2)identity(数字,无需赋值):自动增长。使用的是数据库的自动增长机制。使用于有自动增长机制的机器。Oracle没有自动这增长功能。
特点:只能用在支持自动增长的字段数据库中使用,如MySQL
(3)sequence(数字,无需赋值):序列,使用的是序列的方式完成数据库的主键的生成(Oracle和DB2可以使用),默认使hibernate_sequence这个序列,也可以通过sequence/sequence_name参数赋值
特点:只能在支持序列的数据库中使用,如Oracle
(4)native(等于identity+sequence):本地策略,根据数据库不同自动选择identity和sequence。
特点:根据数据库自动选择,项目中如果用到多个数据库时,可以使用这种方式,使用时需要设置表的自增字段或建立序列,建立表等
(5)uuid/uuid.hex(32位的字符串,无需赋值):适用于字符串类型的主键,是由容器自动生成的一个32位的字符串(uuid.hex代表的是十六进制)
特点:uuid长度大,占用空间大,跨数据库,不用访问数据库就生成主键值,所以效率高且能保证唯一性,移植非常方便,推荐使用
(6)assigned(数据类型不限、save前必须赋值):Hibernate不管理主键,程序员手动设置主键的值
特点:可以跨数据库,人为控制主键生成,但应尽量避免。
以上策略的使用是在generator元素的class属性写上相对应的类名,如
<generator class="increment"></generator>
4、自定义主键生成器:
a、创建主键生成器类,实现org.hibernate.id.IdentifierGenerator接口即可,并还可以实现org.hibernate.id.Configurable接口来读取一些配置信息,如:
package com.zking.two.id;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;
public class IdCreate implements IdentifierGenerator{
public Serializable generate(SharedSessionContractImplementor arg0, Object arg1) throws HibernateException {
return "zking_user_"+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
}
}
b、在*.hbm.xml文件指定主键生成器类,如:
<generator class="com.zking.two.id.IdCreate"></generator>
生成主键的截图: