欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

Hibernate各种主键生成策略与配置详解

程序员文章站 2022-05-29 19:58:00
...

1、assigned 主键由外部程序负责生成,在 save() 之前必须指定一个。Hibernate不负责维护主键生成。与Hibernate和底层数据库都无

1assigned

主键由外部程序负责生成,在 save() 之前必须指定一个。Hibernate不负责维护主键生成。与Hibernate和底层数据库都无关,可以跨数据库。在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免。

ud”是自定义的策略名,人为起的名字,后面均用“ud”表示。

特点:可以跨数据库,人为控制主键生成,应尽量避免。

2increment

Hibernate从数据库中取出主键的最大值(每个session只取1次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库。

Hibernate调用org.hibernate.id.IncrementGenerator类里面的generate()方法,使用select max(idColumnName) from tableName语句获取主键最大值。该方法被声明成了synchronized,所以在一个独立的Java虚拟机内部是没有问题的,然而,在多个JVM同时并发访问数据库select max时就可能取出相同的值,再insert就会发生Dumplicate entry的错误。所以只能有一个Hibernate应用进程访问数据库,否则就可能产生主键冲突,所以不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于群集环境。

官方文档:只有在没有其他进程往同一张表中插入数据时才能使用,在集群下不要使用。

特点:跨数据库,不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于群集环境。

3hilo

hilo(高低位方式high low)是hibernate中最常用的一种生成方式,需要一张额外的表保存hi的值。保存hi值的表至少有一条记录(只与第一条记录有关),否则会出现错误。可以跨数据库。

hibernate_hilo

next_hi

100

hibernate_hilo 指定保存hi值的表名

next_hi 指定保存hi值的列名

100 指定低位的最大值

也可以省略tablecolumn配置,其默认的表为hibernate_unique_key,列为next_hi

100

hilo生成器生成主键的过程(以hibernate_unique_key表,next_hi列为例):

1. 获得hi值:读取并记录数据库的hibernate_unique_key表中next_hi字段的值,数据库中此字段值加1保存。

2. 获得lo值:从0max_lo循环取值,差值为1,当值为max_lo值时,重新获取hi值,然后lo值继续从0max_lo循环。

3. 根据公式 hi * (max_lo + 1) + lo计算生成主键值。

注意:当hi值是0的时候,那么第一个值不是0*(max_lo+1)+0=0,而是lo跳过01开始,直接是123……

max_lo配置多大合适呢?

这要根据具体情况而定,如果系统一般不重启,而且需要用此表建立大量的主键,可以吧max_lo配置大一点,这样可以减少读取数据表的次数,提高效率;反之,如果服务器经常重启,可以吧max_lo配置小一点,可以避免每次重启主键之间的间隔太大,造成主键值主键不连贯。

特点:跨数据库,hilo算法生成的标志只能在一个数据库中保证唯一。

4seqhilo

hilo类似,通过hi/lo算法实现的主键生成机制,只是将hilo中的数据表换成了序列sequence,需要数据库中先创建sequence,适用于支持sequence的数据库,如Oracle

hibernate_seq

100

特点:与hilo类似,只能在支持序列的数据库中使用。

5sequence

采用数据库提供的sequence机制生成主键,需要数据库支持sequence。如oralceDBSAP DBPostgerSQLMcKoi中的sequenceMySQL这种不支持sequence的数据库则不行(可以使用identity)。