在上篇博文中少提了一点,Hibernate 主键的生成策略,这里简单记录一下。
首先先了解一下主键生成策略,就是指主键生成器,负责生成数据表记录的主键。
1 、自动增长identity
identity 由底层数据库于为long 、short 、int 类型生成唯一标识符。identity 是由数据库自己生成的,但这个主键必须设置为自增长。使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence (DB2 和 Oracle 中很常用)
特点:与底层数据库有关,要求数据库支持Identity ,如MySQl 中是 auto_increment, SQL Server 中是Identity ,支持的数据库有MySql 、SQL Server 、DB2 、Sybase 和HypersonicSQL 。 Identity 无需Hibernate 和用户的干涉,使用较为方便,但不便于在不同的数据库之间移植程序。
2 、sequence
Sequence 需要底层数据库支持Sequence 方式,例如DB2 、Oracle 均支持的序列,用于为long 、short 或int 生成唯一标识
特点:需要底层数据库的支持序列,支持序列的数据库有DB2 、PostgreSql 、Qracle 、SAPDb 等在不同数据库之间移植程序,特别从支持序列的数据库移植到不支持序列的数据库需要修改配置文件
3 、hilo
Hilo 使用高低位算法生成主键,高低位算法使用一个高位值和一个低位值,然后把算法得到的两个值拼接起来作为数据库中的唯一主键。Hilo 方式需要额外的数据库表和字段提供高位值来源。默认请况下使用的表是hibernate_unique_key ,默认字段叫作next_hi 。next_hi 必须有一条记录否则会出现错误。
特点:需要额外的数据库表的支持,能保证同一个数据库中主键的唯一性,但不能保证多个数据库之间主键的唯一性。Hilo 主键生成方式由Hibernate 维护,所以Hilo 方式与底层数据库无关,但不应该手动修改hi/lo 算法使用的表的值,否则会引起主键重复的异常。
4 、native
Native 主键生成方式会根据不同的底层数据库自动选择Identity 、Sequence 、Hilo 主键生成方式。比较常用。
特点:根据不同的底层数据库采用不同的主键生成方式。由于Hibernate 会根据底层数据库采用不同的映射方式,因此便于程序移植,项目中如果用到多个数据库时,可以使用这种方式。
5 、seqhilo
sequence 和hilo 的结合,hilo 的高位由sequence 产生,所以也需要底层数据库的支持
通过hilo 算法实现,但是主键历史保存在Sequence 中,适用于支持 Sequence 的数据库,如 Oracle (比较少用)
6 、increment
这个是由Hibernate 在内存中生成主键,每次增量为1 ,不依赖于底层的数据库,因此所有的数据库都可以使用,但问题也随之而来,由于是Hibernate 生成的,所以只能有一个Hibernate 应用进程访问数据库,否则就会产生主键冲突,不能在集群情况下使用
插入数据的时候hibernate 会给主键添加一个自增的主键,但是一个hibernate 实例就维护一个计数器,所以在多个实例运行的时候不能使用这个方法
7 、uuid.hex
UUID 使用128 位UUID 算法生成主键,能够保证网络环境下的主键唯一性,也就能够保证在不同数据库及不同服务器下主键的唯一性。
特点; 能够保证数据库中的主键唯一性,生成的主键占用比较多的存贮空间hibernate 会算出一个16 位的值插入
8 、assigned
由应用程序负责生成主键标识符,往往使用在数据库中没有代理主键,使用的主键与业务相关的情况,如:
<id name="id" column="id" type="string">
<generator class="assigned" />
</id>
这种主键的生成方式不建议使用,在数据库表设计时就应该使用代理主键(surrogate key ),不应使用自然主键(natural key 具有业务含义),在没有指定<generator> 标签时,默认就是assigned 主键的生成方式
在插入数据的时候主键由用户自己添加,hibernate 也不管
9 、foreign
使用外部表的字段作为主键
10 、select
使用触发器生成主键(主要用于早期的数据库主键生成机制,少用)
PS:
代理主键是指与业务无关且能唯一标识数据库中记录, 一般是数据库自动生成的, 比如mysql 可以使用auto_increment,Sql2000 可以使用identity 生成方式,oracle 可以使用sequence 生成方式 自然主键指业务相关, 由用户指定, 且能唯一标识数据库中的任意一条记录
总结:
1 、increment :代理主键,适合于所有数据库,由hibernate 维护主键自增,和底层数据库无关,但是不适合于2 个或以上hibernate 进程。
2 、identity :代理主键,适合于Mysql 或ms sql server 等支持自增的dbms ,主键值不由hibernate 维护。
3 、sequence :代理主键,适合于oracle 等支持序列的dbms ,主键值不由hibernate 维护,由序列产生。
4 、native :代理主键,根据底层数据库的具体特性选择适合的主键生成策略,如果是mysql 或sqlserver ,选择identity ,如果是oracle ,选择sequence 。
5 、hilo :代理主键,hibernate 把特定表的字段作为hign 值,生成主键值
6 、uuid.hex :代理主键,hibernate 采用uuid 128 位算法生成基于字符串的主键值
7 、assign :适合于应用程序维护的自然主键。
以上记住几个常用的,其他的以了解为主。