JPA主键生成策略介绍

《开发框架-Flea》《flea-db》

请添加图片描述

引言

接入JPA框架之前,有必要了解一下JPA的主键生成策略

1. 依赖

<dependency>
	<groupId>org.eclipse.persistence</groupId>
	<artifactId>javax.persistence</artifactId>
	<version>2.1.0</version>
</dependency>

2. GeneratedValue注解

GeneratedValue 是JPA主键生成策略中的一个非常重要的注解。它提供主键值生成策略的规范,可以与 Id 注解一起应用于实体或映射超类的主键属性或字段;它只支持简单的主键,派生的主键不支持使用 。

@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeneratedValue {
    GenerationType strategy() default AUTO;
    String generator() default "";
}

如上代码所示,GeneratedValue 注解有 strategygenerator 两个成员变量。

2.1 主键生成策略【strategy】

持久化提供程序必须使用主键生成策略来生成被注解的实体的主键。这是一个可选项,默认是 GenerationType.AUTO
strategy 的值是主键生成策略枚举类型 GenerationType,包含4个枚举值:【TABLESEQUENCEIDENTITYAUTO】。

2.2 主键生成器【generator】

generator 指定使用的主键生成器的名称,有 SequenceGeneratorTableGenerator 注解。它为持久化提供程序提供 ID 生成器。这也是一个可选项,默认可空。

3. GenerationType

GenerationType 定义主键生成策略的类型。包含如下:

3.1 GenerationType.TABLE

TABLE 指示持久化提供程序必须使用基础数据库表为实体分配主键,以确保唯一性。它的好处是不依赖于具体数据库的实现,代码可移植性高,但由于某些数据库的特性【如主键自增长,序列等等】未能使用到,不推荐优先使用,可作为折中方案。

3.1.1 具体用法

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "FLEA_LOGIN_LOG_GENERATOR")
    @TableGenerator(
        // 唯一的生成器名称,可以由一个或多个类引用以作为id值的生成器。
        name = "FLEA_LOGIN_LOG_GENERATOR",
        // 【可选】存储生成的ID值的表的名称,默认为持久化提供程序选择的名称
        table = "flea_id_generator",
        // 【可选】生成器表所属的数据库目录
        catalog = "",
        // 【可选】生成器表所属的数据库结构
        schema = "",
        // 【可选】表中主键列的名称,默认为持久化提供程序选择的名称
        pkColumnName = "id_generator_key",
        // 【可选】存储最后生成的主键值的列的名称,默认为持久化提供程序选择的名称
        valueColumnName = "id_generator_value",
        // 【可选】ID生成器表中的主键值模板,用于将该生成值集与其他可能存储在表中的值区分开
        // 默认为持久化提供程序选择的值,用以存储在生成器表的主键列中
        pkColumnValue = "pk_flea_login_log_(CREATE_DATE)",
        // 【可选】用于初始化存储最后生成的值的列的初始值,默认值为 0
        initialValue = 0,
        // 【可选】从ID生成器表中分配ID号时增加的数量, 默认值为 50
        allocationSize = 1,
        // 【可选】将在表上放置的其他唯一约束。仅当表生成有效时才使用它们。
        // 除了主键约束之外,还应用了这些约束。默认为无其他约束
        uniqueConstraints = {},
        // 【可选】表的索引。仅当表生成有效时才使用它们。
        // 请注意,不必为主键指定索引,因为主键索引将自动创建。
        indexes = {}
    )
    @Column(name = "login_log_id", unique = true, nullable = false)
    private Long loginLogId; // 登录日志编号

3.1.2 TableGenerator 注解源码

/**
 * 定义一个主键生成器,可以通过名称引用,当在 GeneratedValue注解中指定一个生成器元素时使用。
 * 表生成器可以在实体类或主键字段/属性上指定。生成器名称的作用范围是持久性单元全局的(跨所有生成器类型)。
 *
 */
@Target({TYPE, METHOD, FIELD}) 
@Retention(RUNTIME)
public @interface TableGenerator {

    /** 
     * 必填项,表示唯一的生成器名称,可以被一个或多个类引用,用于生成id值。
     */
    String name();

    /** 
     * 可选项,存储生成的id值的表的名称,默认为持久性提供程序选择的名称。
     */
    String table() default "";

    /** 
	 * 可选项,表所在的目录名称,默认为默认目录。
     */
    String catalog() default "";

    /** 
     * 可选项,表所在的模式名称,默认为用户默认的模式。
     */
    String schema() default "";

    /** 
     * 可选项,表中主键列的名称,默认为提供程序选择的名称。
     */
    String pkColumnName() default "";

    /** 
     * 可选项,存储最后生成的值的列的名称,默认为提供程序选择的名称。
     */
    String valueColumnName() default "";

    /**
     * 可选项,在生成器表中区分此生成的值集合与可能存储在表中的其他值集合的主键值。
	 * 默认为提供程序选择的值,以存储在生成器表的主键列中。
     */
    String pkColumnValue() default "";

    /** 
     * 可选项,用于初始化存储最后生成的值的列的初始值。
     */
    int initialValue() default 0;

    /**
     * 可选项,从生成器分配id号码时每次递增的数量。
     */
    int allocationSize() default 50;

    /**
     * 可选项,要放置在表上的唯一约束条件。仅在表生成器生效时使用。这些约束条件适用于主键约束之外。
     */
    UniqueConstraint[] uniqueConstraints() default {};

    /**
     * 可选项,表的索引。仅在表生成器生效时使用。请注意,对于主键,不必指定索引,因为主键索引将自动创建。
     */
    Index[] indexes() default {};
}

3.2 GenerationType.SEQUENCE

SEQUENCE 指示持久化提供程序必须使用数据库序列为实体分配主键。该策略只适用于部分支持 序列 的数据库系统,比如 Oracle

3.2.1 具体用法

	@Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="PARA_DETAIL_SEQ")
    @SequenceGenerator(
    	// 唯一的生成器名称,可以由一个或多个类引用以作为id值的生成器。
    	name="PARA_DETAIL_SEQ", 
    	// 【可选】主键值对应的数据库序列对象的名称。默认为提供商选择的值。
    	sequenceName="PARA_ID_SEQ",
        // 【可选】生成器表所属的数据库目录
        catalog = "",
        // 【可选】生成器表所属的数据库结构
        schema = "",
        // 【可选】用于初始化存储最后生成的值的列的初始值,默认值为 0
        initialValue = 0,
        // 【可选】从ID生成器表中分配ID号时增加的数量, 默认值为 50
        allocationSize = 1
    )
    @Column(name = "para_id", unique = true, nullable = false)
    public Long getParaId() { return paraId; }

3.2.2 SequenceGenerator 注解源码

/**
 * 定义一个主键生成器,可以通过名称引用,当在GeneratedValue 注解中指定一个生成器元素时。
 * 序列生成器可以在实体类或主键字段或属性上指定。生成器名称的范围是持久单元全局的(跨所有生成器类型)。
 */
@Target({TYPE, METHOD, FIELD}) 
@Retention(RUNTIME)
public @interface SequenceGenerator {

    /** 
     *(必填) 可以被一个或多个类引用的唯一生成器名称,用于主键值的生成器。
     */
    String name();

    /**
     *(可选)用于获取主键值的数据库序列对象的名称。默认为提供程序选择的值。
     */
    String sequenceName() default "";

    /**  
     *(可选)序列生成器的目录。
     */
    String catalog() default "";

    /** 
	 *(可选)序列生成器的模式。
     */
    String schema() default "";

    /** 
     *(可选)序列对象开始生成的值。
     */
    int initialValue() default 1;

    /**
     *(可选)从序列分配序列号时要增加的数量。
     */
    int allocationSize() default 50;
}

3.3 GenerationType.IDENTITY

IDENTITY 指示持久化提供程序必须使用数据库标识列为实体分配主键。该策略只适用于支持 主键自增长 的数据库系统,比如 MySQL。

具体用法如下:

	@Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "para_id", unique = true, nullable = false)
    private Long paraId;        // 参数编号

3.4 GenerationType.AUTO

AUTO 指示持久化提供程序应为特定数据库选择适当的策略。 该生成策略可能期望数据库资源存在,或者可能尝试创建一个数据库资源。如果供应商不支持架构生成或无法在运行时创建架构资源,则供应商可能会提供有关如何创建此类资源的文档。

	@Id
    @GeneratedValue
    @Column(name = "para_id", unique = true, nullable = false)
    private Long paraId;        // 参数编号

4. 各数据库对比

TABLESEQUENCEIDENTITYAUTO
MySQL×
Oracle×
PostgreSQL
SQL Server
DB2

总结

本篇我们介绍了 JPA 主键生成策略,下一篇基于 GenerationType.TABLE 的主键生成器表介绍,敬请期待!!!

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Huazie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值