`
wasw100
  • 浏览: 125996 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

hibernate中使用hilo生成主键的原理

    博客分类:
  • java
阅读更多

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配置小一点,可以避免每次重启主键之间的间隔太大,造成主键值主键不连贯。

分享到:
评论
2 楼 wasw100 2009-09-20  
曾经de迷茫 写道
实际操作中,直接使用sequence或自增字段的时候更常见啊.

如果用sequence的话,数据库的移植性就差了呀,例如MySQL,mssql就不能用,而且hilo效率会高一点吧
1 楼 曾经de迷茫 2009-09-20  
实际操作中,直接使用sequence或自增字段的时候更常见啊.

相关推荐

Global site tag (gtag.js) - Google Analytics