hibernate提供了很多种主键的生成方式,以解决实际开发中各种不同的数据库以及其主键的策略,以前的时候,也有用过很多种,但是都不全面,这次在书上看到了,便记录下来,方便以后查看,使用。
1.Assigned:主键有应用的逻辑产生,数据经由hibernate保存时,主键值以设置完毕,无需hibernate干预。
2.hilo:通过hi/lo算法,实现主键生成机制,需要额外的数据库表保存记录主键生成的历史状态。
3.seqhilo:类似于hilo,也是通过算法,实现主键生成机制,但是无需额外表保存,而是保存在seqence中,此中策略适用于支持seqence的数据库,如oracle等。
4.increment:主键按数值顺序递增。即当前应用中维持了一个变量,以保存当前的最大值,之后每次生成主键,即在上次的数值上加一。这种方式的问题在于,假使有多个实例访问数据库,由于各个实例的主键状态,以及可能生成的同样的主键,以导致主键重复异常,因此,如果有多个实例访问的情况下,需避免使用。
5.identity:采用数据库提供的主键生成机制,如sql server,mysql中的自动增长机制,
6.sequence:采用数据提供的sequence机制生成主键,如oracle sequence。
7.native:由hibernate根据数据库适配器中的定义(即数据库dialect指定的数据库,自动采用identity,hilo,sequence这三种中的一种方式,作为主键生成方式)
8.uuid.hex:由hibernate基于128位唯一算法,根据当前设备ip,时间,jvm启动时间,内部自动增量等4个参数,生成16进制数值,作为主键,这种算法最大程度保证了id的唯一性,几时在多实例并发运行的情况下,也基本不会出现重复。假使真有重复,即设备ip,时间,jvm启动时间,内部增量都相同,那也需要几万年才能出现一次......所以,此方式提供了最好的数据库插入性能和数据库平台适应性。
9.uuid.string:于uuid.hex类似,只是在某些数据库中会出现问题,如PostgreSQL。
10.foreign:使用外部表的字段作为主键。
11.select:hibernate3中新引入的主键机制,主要针对遗留系统改造。因为在早期的一些项目中,主键可能是依赖触发器的捕获操作,来生成主键的。此时,就需要设置为select方式,配置事例为:
<generator class="select"> <param name="key">key_field</param> </generator>
全部的11种全在这里了,由于常用数据库如sqlserver,mysql都提供自动增长,那我们一般可以选择native方式生成主键。不过使用数据提供的机制有时候并不是最好的,在大量并发insert的时候,可能会出现表之间的互锁情况,从而降低整个系统的性能。
另外,sequence作为主键机制的一种,如oracle中,每插入一条数据,hibernate需先向数据库放松一条获取sequence的语句,以得到sequence,从而获取主键的值。这样虽然不会出现问题,但是在高并发的insert情况下,还是对性能有一定的影响。
所以在大多数情况下,假使我们的逻辑允许,可以采用uuid.hex方式生成主键。