添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

在JPA中,我们是通过 @id @GeneratedValue 来指定id主键和id策略的,比如:

@GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id" ) private String id;
  • 1
  • 2
  • 3
  • 4

这样也就指定了id和生成id所使用的策略,下面我们来看一下都有哪些策略呢

4种JPA策略用法

我们点进 @GeneratedValue 源码里可以看到, strategy 属性是由 GenerationType 指定的,我们点进 GenerationType 里面可以看到这里定义了四种策略:
- TABLE :使用一个特定的数据库表格来保存主键。
- SEQUENCE :根据底层数据库的序列来生成主键,条件是数据库支持序列。
- IDENTITY :主键由数据库自动生成(主要是自动增长型)
- AUTO :主键由程序控制(也是默认的,在指定主键时,如果不指定主键生成策略,默认为AUTO)
这些策略也不是所有数据库都支持的,支持情况如下表:

策略\数据库 mysql oracle postgreSQL kingbase
TABLE 支持 支持 支持 支持
SEQUENCE 不支持 支持 支持 支持
IDENTITY 支持 不支持 支持 支持
AUTO 支持 支持 支持 支持

Hibernate拓展id策略

当然,很多时候,这么几种策略并不够用,这里hibernate也拓展了JPA的id策略,我们可以在 org.hibernate.id.IdentifierGeneratorFactory 中看到,主要提供了这么些策略:
1. native : 对于oracle采用Sequence方式,对于MySQL和SQL Server采用identity(自增主键生成机制),native就是将主键的生成工作交由数据库完成,hibernate不管(很常用)。
2. uuid : 采用128位的uuid算法生成主键,uuid被编码为一个32位16进制数字的字符串。占用空间大(字符串类型)。
3. hilo : 使用hilo生成策略,要在数据库中建立一张额外的表,默认表名为hibernate_unique_key,默认字段为Integer类型,名称是next_hi(比较少用)。
4. assigned : 在插入数据的时候主键由程序处理(很常用),这是 generator 元素没有指定时的默认生成策略。等同于JPA中的AUTO。
5. identity : 使用SQL Server和MySQL的自增字段,这个方法不能放到Oracle中,Oracle不支持自增字段,要设定sequence(MySQL和SQL Server中很常用)。等同于JPA中的IDENTITY。
6. select : 使用触发器生成主键(主要用于早期的数据库主键生成机制,少用)。
7. sequence : 调用底层数据库的序列来生成主键,要设定序列名,不然hibernate无法找到。
8. seqhilo : 通过hilo算法实现,但是主键历史保存在Sequence中,适用于支持Sequence的数据库,如Oracle(比较少用)。
9. increment : 插入数据的时候hibernate会给主键添加一个自增的主键,但是一个hibernate实例就维护一个计数器,所以在多个实例运行的时候不能使用这个方法。
10. foreign : 使用另外一个相关联的对象的主键。通常和联合起来使用。
11. guid : 采用数据库底层的guid算法机制,对应MYSQL的uuid()函数,SQL Server的newid()函数,ORACLE的rawtohex(sys_guid())函数等。
12. uuid.hex : 看uuid,建议用uuid替换。
13. sequence-identity : sequence策略的扩展,采用立即检索策略来获取sequence值,需要JDBC3.0和JDK4以上(含1.4)版本 。
具体使用就是多了一个 @GenericGenerator 注解,指定策略,指定自定义名称,然后在 @GeneratedValue 中使用该策略,比如:

@GeneratedValue (generator = "myIdStrategy" ) @GenericGenerator (name = "myIdStrategy" , strategy = "uuid" ) @Column (name = "id" ) private String id;
  • 1
  • 2
  • 3
  • 4
  • 5

其他的类似,就不再多举例了

到这里已经有很多策略供我们使用了,但是呢,有时候比如分布式系统中要求全局id唯一,或者其他一些场景,要求我们有自己的策略,那么该怎么做呢?

使用的id策略(以snowflake为例)

在看其他策略源码的时候,我们发现他们实现了这样一个接口 IdentifierGenerator ,他位于 org.hibernate.id 包下,我们进入该类,就可以看到源码注释上写着用户实现此接口可以实现自定义id策略
那么就很简单了,我们实现一下这个接口:

public class SnowflakeId implements IdentifierGenerator{
    @Override
    public Serializable generate(SessionImplementor s, Object obj) {
        return getId() + "";
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

实现 generate 方法,方法体调用我们生成id的方法就好了,这里省略了生成过程,有需要可以去我代码里找一下。

注意 IdentifierGenerator 接口里面还写了一句注释,必须要实现一个默认的无参构造。当时实现的就少看了这一句,折腾了好久(手动捂脸)。所以大致是这样的:

public class SnowflakeId implements IdentifierGenerator{
    public SnowflakeId() {
    @Override
    public Serializable generate(SessionImplementor s, Object obj) {
        return getId() + "";
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

自定义完了之后,我们只需要在指定策略的时候使用我们自定义的就好了, @GenericGenerator 注解的 strategy 属性上说了,使用非默认策略的时候,需要使用全类名,即:

@GeneratedValue (generator = "snowFlakeId" ) @GenericGenerator (name = "snowFlakeId" , strategy = "top.felixu.idworker.SnowflakeId" ) @Column (name = "id" ) private String id;
  • 1
  • 2
  • 3
  • 4
  • 5

这样我们就实现了自己的id策略了

本篇主要介绍 spring data jpa 提供的 ID 生成 策略 (AUTO、TABLE、SEQUENCE、 ID ENTITY、UU ID ),并介绍了如何 自定义 ID 生成 策略 。 在使用的 JPA 的时候,通常会在实体类里面为主键 id 配置 id 的生成 策略 ,比如下面这样的,生成UU ID 作为主键 @GeneratedValue(generator="sys_u id ") @GenericGenerator(name="sys_u id ", strategy="uu id ") private String id ; 但是,这个有时候不能完全满足我们的需要。我们需要一个 自定义 id ,比... 根据实际需要,还可以选择其他主键生成 策略 ,如GenerationType.AUTO、GenerationType.SEQUENCE等。2. 在上述示例中,使用@GeneratedValue注解指定主键的生成 策略 为GenerationType. ID ENTITY,表示主键值由数据库自动生成。4. 在进行数据访问操作时,可以通过主键字段 id 来进行数据的查询、更新和删除等操作。3. 在数据库表中,对应的主键字段会被自动创建为Long类型的主键。在 Spring Boot 中添加主键类型为Long的主键。 需要实现 Id entifierGenerator并实现 generate()方法。在generate()方法里面去写 自定义 的主键生成 策略 @Component@Overr id e//获取table注解,通过table获取表名//如果获取不到Table则返回随机 ID // 获取表名// 获取实体中的自增列,这里认为@javax.persistence. Id 或@org. spring framework. data .annotation. Id 修饰的属性就是我们要的。 import com.fasterxml.jackson.annotation.JsonFormat; import org.hibernate.annotations.GenericGenerator; import javax.persistence.GeneratedValue; import javax.persistence. Id ; import javax.persistence Spring Data JPA Spring Data 的一个子项目,通过提供基于 JPA 的Repository极大的减少了 JPA 作为数据访问方案的代码量,你仅仅需要编写一个接口集成下 Spring Data JPA 内部定义的接口即可完成简单的CRUD操作。 本篇文章引导你通过 Spring Boot Spring Data JPA 和MySQL实现设置@ id @generatedvalue初始值从100... 关于 Spring - data - jpa 的配置+ Spring boot + Spring - data - jpa 的简单操作简单操作+分布式服务设置一个永远不重复的 ID 初学 Spring 套餐家族中的 Spring - data - jpa 发现可以更简单的实现一些基本的增删改查,以下是一些基础操作,希望可以给初学者一些帮助。 spring 家族 Spring Boot spring Cloud Spring framework... 在 Spring Boot 中,@ Id 注解是一个非常重要的注解,用于标识实体类中的主键字段。使用 @ Id 注解可以帮助我们方便地进行持久化、查询、更新等操作。同时,@ Id 注解还可以与其他注解结合使用,例如 @GeneratedValue、@Column 等,用于控制主键生成 策略 和数据库字段的映射关系。希望本文对您有所帮助,欢迎留言交流。 一、 JPA 通用 策略 生成器  通过annotation来映射hibernate实体的,基于annotation的hibernate主键标识为@ Id , 其生成规则是由@GeneratedValue设定的。这里的@ id 和@GeneratedValue都是 JPA 的标准用法, JPA 提供四种标准用法,由@GeneratedValue的源代码可以明显看出。 @Target({METHOD,FIELD} @GeneratedValue(strategy = GenerationType. ID ENTITY, generator = " id OrGenerate") @GenericGenerator(name = " id OrGenerate", strategy = "com.sunlands.util. Id OrGenerate") Integer id ;