zoukankan      html  css  js  c++  java
  • Hibernate 之主键生成策略小总结

    主键生成策略大致分两种:

    • 手工控制策略
    • 自动生成策略【框架自动生成和数据库自动生成】

    手工控制策略:

    assigned:类型是任意的,需要在 save() 到数据库前,编码人员手工设置主键值,也就是调用对象的 setter方法进行赋值操作。

    注:可以跨数据库,但是手动控制不能保证不重复,不推荐使用。

    自动生成策略:

    1 . uuid:自动生成 32 位及以上的随机字符串,生成的依据包括但不限于网卡地址,时间值等。

    注:可以跨数据库,效率高,能保证唯一性,推荐使用【虽然占用空间大】

    2 . increment:自动获取数据库中主键的最大值【整数型】,自动加一后赋值给对象。

    注:可以跨数据库,但是不适合群集下使用,多线程并发更新数据库会取出相同的主键值。

    3 . identity:数据库主键设为自动增长【整数型】。

    注:适用于MySQL,DB2,SQLserver,不适用于Oracle。

    4 . sequence:数据库主键设为自动增长【整数型】。

    注:适用于Oracle。

    5 . hilo:Hibernate 中最常用的一种生成方式,需要一张额外的表保存 hi 的值。保存 hi 值的表至少有一条记录(只与第一条记录有关),否则会出现错误。

    <id name="id" column="id">
        <generator class="hilo">
            <param name="table">hibernate_hilo</param>
            <param name="column">next_hi</param>
            <param name="max_lo">100</param>
        </generator>
    </id>
    
    <!--  指定保存hi值的表名  -->
    <param name="table">hibernate_hilo</param>
    <!--  指定保存hi值的列名  -->
    <param name="column">next_hi</param> 
    <!--  指定低位的最大值  -->
    <param name="max_lo">100</param> 
    <!--  也可以省略table和column配置,其默认的表为hibernate_unique_key,列为next_hi  -->
    <id name="id" column="id">
        <generator class="hilo">
            <param name="max_lo">100</param>
        </generator>
    </id>

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

    • 获得hi值:读取并记录数据库的hibernate_unique_key表中next_hi字段的值,数据库中此字段值加1保存。
    • 获得lo值:从0到max_lo循环取值,差值为1,当值为max_lo值时,重新获取hi值,然后lo值继续从0到max_lo循环。
    • 根据公式 hi * (max_lo + 1) + lo计算生成主键值。

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

    那max_lo配置多大合适呢?

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

    注:可以跨数据库,hilo算法生成的标志只能在一个数据库中保持唯一。

    6 . native:native由hibernate根据使用的数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式,灵活性很强。如果能支持identity则使用identity,如果支持sequence则使用sequence。

    注:根据数据库自动选择,项目中如果用到多个数据库时,可以使用这种方式,使用时需要设置表的自增字段或建立序列,建立表等。

    7 . foreign:用于一对一关联关系中。

    <id name="id" column="id">
        <generator class="foreign">
             <param name="property">user</param>
        </generator>
    </id>
    <one-to-one name="user" class="com.msym.domain.User" constrained="true" />

    注:用的少,只用于一对一关联关系【一对一关联关系一般都合为一张表】。

    小总结:

    主键生成策略

    由谁生成OID

    数据库id字段类型

    兼容数据库

    assigned

    程序员控制输入

    不限定

    所有

    uuid

    Hibernate内部控制输入

    字符串类型

    所有

    increment

    Hibernate内部控制输入

    整型

    所有

    identity

    数据库底层控制输入

    整型自增

    Mysql可用

    sequence

    数据库底层控制输入

    整型

    Oracle可用

    native

    数据库底层控制输入

    整型自增

    所有

  • 相关阅读:
    SDOI2019游记
    noi.ac309 Mas的童年
    51nod1237 最大公约数之和
    loj6074 子序列
    noi.ac89A 电梯
    51nod97B 异或约束和
    bzoj4490 随机数生成器Ⅱ加强版
    CF55D Beautiful numbers
    CF24D Broken robot
    CF226D The table
  • 原文地址:https://www.cnblogs.com/daimajun/p/7183569.html
Copyright © 2011-2022 走看看