一 什么是对象标识符(OID object id)
Hibernate中的持久化对象对应数据库中的一张数据表,因此区分不同的持久化对象,在Hibernate中是通过OID(对象标识符)来完成的,从表的角度看,OID对应表的主键。从类的角度看OID对应类的主键属性。
二 主键增长策略
①increment标识符生成器
由Hibernate自动以递增方式生成标识符,每次增量为1。
优点:不依赖于底层数据库系统,适用于所有的数据库系统。
缺点:适用于单进程环境下,在多线程环境下很可能生成相同主键值。
OID必须为数值类型,比如long,int,short类型。
配置方式:
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
②identity标识符生成器
由底层数据库生成标识符。
前提条件:数据库支持自动增长字段类型,每次增加1,比如(sql server,mysql),而且OID必须为数值类型,比如long,int,short类型。
配置文件:
<id name=“id” type=“long” column=“ID”>
<generator class=“identity”/>
</id>
③sequence标识符生成器
依赖于底层数据库系统的序列
前提条件:需要数据库支持序列机制(如:oracle等),而且OID必须为数值类型,比如long,int,short类型。
配置文件:
<id name=“id” type=“java.lang.Long” column=“ID”>
<generator class=“sequence”>
<param name=“sequence”>my_seq</param>
</generator>
</id>
④native标识符生成器
native生成器能根据底层数据库系统的类型,自动选择合适的标识符生成器,因此非常适用于跨数据库平台开发,他会由Hibernate根据数据库适配器中的定义,自动采用identity,hilo,sequence的其中一种作为主键生成方式,但是OID必须为数值类型(比如long,short,int等)
配置文件:
<id name=“id” type=“java.lang.Integer” column=“ID”>
<generator class=“native”/>
</id>
⑤hilo标识符生成器
hilo标识符生成器由Hibernate按照一种high/low算法生成标识符,他从数据库中的特定表的字段中获取high值,因此需要额外的数据库表保存主键生成的历史状态,hilo生成方法不依赖于底层数据库,因此适用于每一种数据库,但是OID必须为数值类型(long,int,shor类型)。
配置文件:
<id name=“id” type=“java.lang.Integer” column=“ID”>
<generator class=“hilo”>
<param name=“table”>my_hi_value</param>
<param name=“column”>next_value</param>
</generator>
</id>
⑥uuid标识符生成器
由Hibernate基于128位唯一值产生算法,根据当前设备IP,时间,JVM启动时间,内部自增量等4个参数生成16进制数值作为主键,一般而言,利用uuid方式生成的主键提供最好的数据插入性能和数据库平台适应性. OID一般使用是String类型。
配置文件:
<id name="id" type="java.lang.String" column="ID">
<generator class="uuid"/>
</id>
⑦assigned标识符生成器
采用assign生成策略表示由应用程序逻辑来负责生成主键标识符,OID类型没有限制。
配置文件:
<id name="id" type="java.lang.Integer" column="ID">
<generator class="assigned"/>
</id>
⑧映射复合主键—略讲
为了讲解复合主键,我们先建一张表:
create table CUSTOMERS
( CUSNAME VARCHAR2(40) not null,
HOMEADDRESS VARCHAR2(50) not null,
BIRTHDAY DATE not null,
SEX VARCHAR2(2),
CUSCOMPANY VARCHAR2(40)
)
设置复合主键
alter table CUSTOMERS
add constraint CUS_PK primary key (CUSNAME, HOMEADDRESS, BIRTHDAY)
第一种方式:以独立主键类映射复合主键,这样可以达到将逻辑加以隔离的目的,配置文件如下:
<composite-id name="id" class="com.test.model.pojo.CustomersId">
<key-property name="cusname" type="java.lang.String">
<column name="CUSNAME" length="40" />
</key-property>
<key-property name="homeaddress" type="java.lang.String">
<column name="HOMEADDRESS" length="50" />
</key-property>
<key-property name="birthday" type="java.util.Date">
<column name="BIRTHDAY" length="7" />
</key-property>
</composite-id>
⑨foreign
在one-to-one的关系中,由另一张表的主键(Person) 来决定自己主键/外键( IdCard)。
三 给出一个的选择简单原则
针对oracle,如果主键是int/long/short,建议使用sequence,如果主键是String,使用uuid或者assinged。
针对mysql,如果主键是int/long/short,建议使用increment/assigend,如果是字串,使用UUId/assigned。
针对sql server,如果主键是int/long/short,建议使用identity/native/assinged,如果主键是字串,使用uuid/assigned。
one-to-one,又是基于主键的则使用foreign。