Hibernate各种主键生成策略与配置详解 1、assigned 主键由外部程序负责生成,在 save() 之前必须指定一个。Hibernate不负责维护主键生成。与Hibernate和底层数据库都无关,可以跨数据库。在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免。 ### hibernate主键生成策略详解 #### 一、assigned **assigned** 主键生成策略意味着主键的值是由外部程序负责生成的,并且在执行 `save()` 方法之前必须明确指定一个值。在这种策略下,Hibernate 不参与主键的生成过程,也不对主键的生成进行维护或管理。这种策略与 Hibernate 和底层数据库都无关,因此可以跨数据库使用。 在存储对象之前,开发者必须手动使用主键的 setter 方法给主键赋值。至于主键的具体生成方式,完全由开发者自行决定。由于这种方式完全依赖于开发者的实现,因此可能会带来一定的不确定性,特别是在高并发环境下。因此,尽管 **assigned** 策略提供了一定的灵活性,但通常建议尽量避免使用它。 #### 二、increment **increment** 策略由 Hibernate 从数据库中取出主键的最大值(每个 session 只取一次),并在此基础上每次递增 1 来生成新的主键值。这一策略不依赖于底层数据库的具体实现,因此可以在不同的数据库之间通用。 在内部,Hibernate 会调用 `org.hibernate.id.IncrementGenerator` 类中的 `generate()` 方法来获取当前主键的最大值,通常是通过执行 `SELECT MAX(idColumnName) FROM tableName` 这样的 SQL 语句来完成的。值得注意的是,该方法被声明为 synchronized,这意味着在同一 JVM 内部可以确保线程安全,但在多 JVM 并发访问同一数据库时,则可能出现主键冲突的问题,尤其是在插入操作频繁发生的场景下。因此,这种策略更适合单个应用程序访问数据库的场景,而不适用于集群环境或需要高度并发的应用程序。 #### 三、hilo **hilo**(即高位/低位方式 high-low)是 Hibernate 中常用的主键生成策略之一。它需要一张额外的表来保存高位值 hi 的信息。该表至少需要有一条记录,否则会导致错误。这种策略同样可以跨数据库使用。 在配置文件中,可以通过以下方式指定 hilo 策略: ```xml <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> ``` 其中: - `<param name="table">hibernate_hilo</param>` 指定保存 hi 值的表名。 - `<param name="column">next_hi</param>` 指定保存 hi 值的列名。 - `<param name="max_lo">100</param>` 指定低位的最大值。 如果不指定 `<param name="table">` 和 `<param name="column">`,则会使用默认的表名 `hibernate_unique_key` 和列名 `next_hi`。 **hilo** 算法生成主键的过程如下: 1. 获取 hi 值:读取并记录数据库中 `hibernate_unique_key` 表中 `next_hi` 字段的值,并将该字段的值加 1 后保存回数据库。 2. 获取 lo 值:从 0 开始,一直到 max_lo 循环取值,步进为 1。当达到 max_lo 的值时,再次获取 hi 值,然后 lo 值继续从 0 循环到 max_lo。 3. 根据公式 `hi * (max_lo + 1) + lo` 计算出最终的主键值。 需要注意的是,当 hi 的初始值为 0 时,第一个生成的主键值不是 0,而是从 1 开始递增。 对于 `max_lo` 的设置,可以根据实际需求调整。如果系统很少重启,且需要频繁生成大量主键,则可以将 `max_lo` 设置得较大,以减少读取数据表的频率,从而提高性能。相反地,如果服务器经常重启,则可以将 `max_lo` 设置得较小,以避免重启后主键值间的跳跃过大。 **hilo** 策略的特点在于它可以跨数据库使用,并且通过 hi-lo 算法生成的主键值只能在一个数据库内保证唯一性。 #### 四、seqhilo **seqhilo** 策略与 **hilo** 类似,同样是基于 hi/lo 算法实现的主键生成机制,不同之处在于它使用了序列(sequence)而不是额外的数据表来保存高位值 hi。这种策略适用于支持序列的数据库,例如 Oracle 数据库。 配置示例: ```xml <id name="id" column="id"> <generator class="seqhilo"> <param name="sequence_name">my_seq</param> <param name="max_lo">100</param> </generator> </id> ``` 其中: - `<param name="sequence_name">my_seq</param>` 指定了序列名称。 - `<param name="max_lo">100</param>` 指定了低位的最大值。 **seqhilo** 策略的主要特点是使用序列来管理高位值 hi,因此无需额外的表来存储 hi 的值,减少了数据库的操作,提高了性能。但需要注意的是,这种策略仅适用于支持序列的数据库。 Hibernate 提供了多种主键生成策略,每种策略都有其适用的场景和限制条件。选择合适的策略对于保证应用的正确性和性能至关重要。开发者在选择时应考虑应用程序的需求以及所使用的数据库类型等因素。
剩余8页未读,继续阅读
- 粉丝: 1
- 资源: 1
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助