hilo是hibernate中最长用的一种生成方式,hibernate给出了hilo 和 seqhilo两种生成器,他们的分别向下面一样配置
<id name="id" type="int" column="id"> <generator class="hilo"> <param name="table">wasw100_hilo_tbl</param> <param name="column">next_value</param> <param name="max_lo">100</param> </generator> </id>
<id name="id" type="int" column="id"> <generator class="seqhilo"> <param name="sequence">hi_value</param> <param name="max_lo">100</param> </generator> </id>
seqhilo生成器需要数据库对sequence的支持,这里只讨论更通用的hilo生成器。
如果你按照下面的方式配置
<generator class="hilo"> <param name="max_lo">100</param> </generator>
这样的缺省配置对应的数据库表是:hibernate_unique_key,对应的数据库字段是:next_hi。next_hi必须有一条记录否则会出现错误。
讨论前先说明几个简写的意义,以最上面那个配置为例:
hi: 高值--从数据库wasw100_hilo_tbl读取的next_value值
lo: 低值--hibe自动维护,从0到max_lo(看下面)
max_lo: 配置文件中<param name="max_lo">100</param>的值,这里是100
hibernate根据hilo生成器生成主键的过程:
1.读取并记录数据库的wasw100_hilo_tbl表中next_value字段的值,数据库中此字段值加1保存
2.hibernate取得lo值(0到max_lo-1循环,lo到max_lo时,执行步骤1,然后lo继续从0到max_lo循环)
取得hi值和lo值后,根据下面的公式计算主键值:
hi*(max_lo+1)+lo;
例如:
hi初始为2,max_lo为3
生成的值依次是:
读取hi为2,写到数据库为3
2*(3+1)+0=8
2*(3+1)+1=9
2*(3+1)+2=10
2*(3+1)+3=11
这有次读写表wasw100_hilo_tbl操作,hi变为3,数据库成为4
3*(3+1)+0=12
3*(3+1)+1=13
关闭数据库,下次打开时,读取hi值为4,数据库变为5
4*(3+1)+0=16
但是有一种特殊情况,就是hi是0的时候,那么第一个值不是0*(max_lo+1)+0=0
而是lo跳过0从1开始,直接是1、2、3……
那max_lo配置多大合适呢?
这要根据具体情况而定,如果系统一般不重启,而且需要用此表建立大量的主键,可以吧max_lo配置大一点,这样可以减少读取数据表wasw100_hilo_tbl的次数,提高效率;反之,如果服务器经常重启,可以吧max_lo配置小一点,可以避免每次重启主键之间的间隔太大,造成主键值主键不连贯。