`

hibernate主键生成策略

阅读更多

下面是在CSDN上看到的一篇文章,保存在我的txt中,现在也贴出来.

介绍hibernate主键生成策略的文章网上比比皆是。但是如何选择一个适合于自己项目的主键生成策略缺没有什么好的指导性文章。在此希望与大家议论。 
hibernate的主键生成策略主要包括了"uuid2","guid","uuid","uuid.hex","hilo","assigned","identity","select","sequence","seqhilo","increment","foreign","sequence-identity","enhanced-sequence","enhanced-table",全部在org.hibernate.id.factory.DefaultIdentifierGeneratorFactory中定义,至于每种生成策略的简单描述不是本文重点议论的话题,我们主要将着眼点放到各生成器的优缺点上去(当然都有优点只是适合不适合,本文就想议论这个)
hibernate主键生成采用策略模式进行设计,各个生成策略都直接或或者间接实现了IdentifierGenerator接口,此接口只有一个方法publicSerializablegenerate(SessionImplementorsession,Objectobject)throwsHibernateException;这个方法由各个类实现具体的生成逻辑。
我们来一个一个看一下:

1、uuid2,IdentifierGenerator的实现类是UUIDGenerator,具体由UUIDGenerationStrategy策略负责生成,它有两个实现StandardRandomStrategy和CustomVersionOneStrategy,他们都是使用java.util.UUID的api生成主键的,StandardRandomStrategy最终由UUID.randomUUID();生成,而CustomVersionOneStrategy则采用版本号与位运算通过构造函数newUUID(mostSignificantBits,leastSignificantBits);生成。
特点是:不需要和数据库交互,可根据RFC4122定义的5中变量控制具体的生成策略(因为符合RFC4122定义,所以避免了警告信息) 

2、guid,IdentifierGenerator的实现类是GUIDGenerator,通过session.getFactory().getDialect().getSelectGUIDString();获得各个数据库中的标示字符串,mySql用"selectuuid()";oracle9g用return"selectrawtohex(sys_guid())fromdual";其他看源码吧。
特点是:需要和数据库进行一次查询才能生成。数据库全局唯一。 

3、uuid和uuid.hex 两个一个东西。IdentifierGenerator的实现类是UUIDHexGenerator,通过StringBuffer(36).append(format(getIP())).append(sep).append(format(getJVM())).append(sep).append(format(getHiTime())).append(sep).append(format(getLoTime())).append(sep).append(format(getCount()))生成。
特点:不需要和数据库交互,全网唯一。 

4、hilo,IdentifierGenerator的实现类TableHiLoGenerator,逻辑较为复杂,通过高低位酸腐生成,但是需要给定表和列作为高值的源。加上本地的地位计算所得。复杂有兴趣看"数据建模101"(Ambler,2002)
特点;需要和数据库交互,全数据库唯一,与guid不同的是,在标识符的单个源必须被多个插入访问时可以避免拥堵。 

5、assigned IdentifierGenerator的实现类Assigned,没有生成逻辑,如果为空就抛出异常。 
特点:不需要和数据库交互,自己管理主键生成,显示的指定id. 

6、identity,IdentityGenerator并没有直接实现IdentifierGenerator,而是扩展了AbstractPostInsertGenerator,并实现PostInsertIdentifierGenerator,而PostInsertIdentifierGenerator实现了IdentifierGenerator. 通过IdentifierGeneratorHelper类生成,这个比较特殊,它返回是个常量"POST_INSERT_INDICATOR",指在数据库插入后时生成,然后返回数据库生成的id,还有个常量"SHORT_CIRCUIT_INDICATOR",是用外键ForeignGenerator时使用的。
特点:需要和数据库交互,数据插入后返回(反查)id,同一列唯一 

7、select, SelectGenerator扩展了AbstractPostInsertGenerator实现了Configurable接口,而AbstractPostInsertGenerator实现了PostInsertIdentifierGenerator。所以具有和identity类似的行为,有数据库触发器生成。
特点:需要和数据库交互, 

8、sequence,SequenceGenerator实现了PersistentIdentifierGenerator接口,和Configurable接口,PersistentIdentifierGenerator接口扩展IdentifierGenerator接口,通过数据库不同获取不同的取值语句dialect.getSequenceNextValString( sequenceName );然后进行查询,缓存到IntegralDataTypeHolder中,通过generateHolder( session ).makeValue();获得。 
特点:需要和数据库交互(但不是每次都是)。sequence唯一 

9、seqhilo,扩展了SequenceGenerator,处理逻辑和hilo相同,值不过是使用一个具名的数据库序列来生成高值部分。 
特点:同4 

10、increment,IdentifierGenerator的实现类IncrementGenerator,并实现了Configurable接口。数据库启动时查询表的最大主键列支,并通过IntegralDataTypeHolder缓存。插入一条,它自加一。
特点:仅需要首次访问数据库。 

11、foreign,IdentifierGenerator的实现类ForeignGenerator,通过给定的entityName和propertyName查询获得值。
特点:需要和数据库访问。 

后面的几种基本上是上面各种逻辑的组合,不在一一分析了。enhanced-table是通过数据库中的表生成id的。 

从上面可以看到,虽然这么多,但是大体可以分为三类 
1、不需要和数据库交互就可以生成id的。包括uuid,uuid2,uuid.hex 
2、需要和数据库交互以生成id的。guid,hilo,identity,select,sequence,seqhilo,increment、foreign 
  可细分为一个id一个sql:guid,identity,select,foreign 
  一个sql多个id:hilo,sequence,seqhilo,increment 
3、不用交互我自己管理assigned 

提高系统新能的主要做法就是显著减少数据库的访问次数。通过上面的分析,可作为我们考虑的一个指标。 
大家议论下,自己项目中的主键生成是什么策略,以及优缺点是什么? 

这是为csdn的大牛ldh911的议论以下继续 
◎ 关于ID生成 
—— 我一贯认为入手都是Assigned,也就是说我考虑的方式是:如果我自己来生成这个ID的话,最优选择是啥?然后再看看Hibernate之类的是否能提供我最优选择所期望的。
—— 是否集群环境?是第一个要考虑的因素,但基本上我都以集群环境为必要条件; 
—— 然后是:超高并发生成?超高并发查询?ID是否需要存在语义?等问题。 

◎ 不同的ID对我来说有啥区别? 
—— UUID:极其适用于分布式计算环境(超越集群了),但ID将不能承载任何语义,高并发生成支持较好,超高并发查询存在数据库端不易优化的问题。
—— 数据库端seq:适用于集群环境,ID可承载某些语义(比如生成时间上较大范围的先后顺序),超高并发生成较搓,超高并发查询可做特定分区优化。 

◎ 最终呢? 
—— 最终基本上都选择UUID或其变体,因为有时候我还是需要ID承载少量语义的,比如我可能会关心这个UUID究竟是哪个终端生成的,你可能会说:可以换个字段保存啊?这类问题就智者见智仁者见仁了。

分享到:
评论

相关推荐

    Hibernate主键生成策略

    ### Hibernate 主键生成策略详解 #### 一、概述 Hibernate 是一款开源的对象关系映射 (ORM) 框架,它允许开发人员将 Java 对象映射到数据库表中的记录,从而极大地简化了数据访问层的开发工作。在 Hibernate 中,...

    常用Hibernate主键生成策略

    ### 常用Hibernate主键生成策略详解 #### 一、引言 在数据库设计与操作过程中,主键是确保数据唯一性的关键要素之一。在实际应用中,开发者经常需要处理不同类型的数据库,并且需要应对各种不同的主键生成需求。...

    hibernate 主键生成策略

    ### Hibernate 主键生成策略详解 Hibernate 是一款流行的 Java 持久层框架,它提供了对象关系映射(ORM)的功能,使得 Java 开发者能够更高效地与数据库进行交互。在 Hibernate 中,主键生成策略是一项核心功能,...

    Hibernate主键生成策略.doc

    Hibernate主键生成策略.docHibernate主键生成策略.doc

    hibernate主键生成策略详解

    ### hibernate主键生成策略详解 #### 一、assigned **assigned** 主键生成策略意味着主键的值是由外部程序负责生成的,并且在执行 `save()` 方法之前必须明确指定一个值。在这种策略下,Hibernate 不参与主键的...

    Hibernate中主键生成策略

    在Java的持久化框架Hibernate中,主键生成策略是一个至关重要的概念,它决定了数据库表中主键值如何自动生成。主键通常是表中唯一标识记录的一列,对于数据的完整性和一致性至关重要。以下是对Hibernate中主键生成...

    Hibernate主键生成策略.docx

    ### Hibernate 主键生成策略详解 #### 一、概述 Hibernate 是一种流行的 Java 持久化框架,它简化了数据库操作,并提供了多种主键生成策略。主键是表中的一个或多个字段组合,用于唯一标识表中的每一条记录。...

    Hibernate各种主键生成策略

    Hibernate各种主键生成策略详解,包括 assigned increment hilo seqhilo sequence identity native uuid foreign uuid.hex sequence-identity 等

    Hibernate各种主键生成策略与配置详解

    ### Hibernate 主键生成策略与配置详解 #### 一、概述 在使用Hibernate进行持久化操作时,合理选择和配置主键生成策略对于确保数据的一致性和优化性能至关重要。本文将详细介绍几种常见的主键生成策略,并结合示例...

    Java探索之Hibernate主键生成策略详细介绍

    Hibernate主键生成策略详细介绍 在Java探索中,Hibernate提供了多种主键生成策略,满足不同场景下的需求。下面是对Hibernate主键生成策略的详细介绍: 1. Increment主键生成策略 Increment主键生成策略是由...

    持久化类主键生成策略+例子

    ### Hibernate主键生成策略 1. **`native`**:类似于JPA的`GenerationType.AUTO`,根据底层数据库选择合适的生成策略。 2. **`identity`**:相当于JPA的`GenerationType.IDENTITY`,适合自动增长主键的数据库。 3...

    hibernate的主键生成策略

    以下是对Hibernate主键生成策略的详细说明: 1. **assigned**: 这种策略要求用户在调用`save()`方法之前手动设置主键值。Hibernate不参与主键的生成,这意味着主键生成完全由应用控制,可以与数据库无关。这种...

Global site tag (gtag.js) - Google Analytics