JPA主键生成策略介绍

2023-11-11

引言

接入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. 各数据库对比

TABLE SEQUENCE IDENTITY AUTO
MySQL ×
Oracle ×
PostgreSQL
SQL Server
DB2

总结

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JPA主键生成策略介绍 的相关文章

随机推荐

  • proteus中继电器怎么找_(踩坑记录)——数电仿真proteus/ewb

    我不管 从今天开始我要隐姓埋名的在知乎记录各种学习和生活上遇到的坎了 因为实在不知道记录在哪里方便查找 为什么要记录呢 还不是我脑子不好 彻底卸载proteus 正常卸载 删除注册表 win R输入以下 数电仿真实验 1 一 逻辑门 74L
  • 冷月手撕408之操作系统(5)-进程概述

    操作系统的进程概述主要是介绍了进程的概念 进程的组成 进程实体 进程的特征 进程的五状态模型 进程控制 其中重点掌握PCB 五状态模型及其状态转换 主要的重点冷月做出了标识 知识点如下图 pdf版或xmind源文件请关注公众号 学长冷月 回
  • 【算法】排序(sort排序函数和冒泡、选择、插入、快速排序)

    记录目前学到的4种排序 sort函数排序 冒泡排序 选择排序 插入排序 sort函数排序 1 对数组进行排序 要加函数头 include
  • ChatGPT:我的生活工作“解忧公主”

    1 概述 在这个充满活力与挑战的时代 我们的生活和工作总是充满了各种问题 幸运的是 有了 ChatGPT 这位 解忧公主 我们能轻松应对这些问题 高效地度过每一天 本文将分享 ChatGPT 如何成为我们生活工作中的万能钥匙 我们将从以下几
  • python3的面向对象

    python的面向对象也很强大 支持多继承 php和java都是单继承 但都可以实现其他接口 self 类似java的this test py usr bin python3 基类 class Base 父类属性 name age 60 定
  • Windows下fopen,fclose

    Fopen fclose 在头文件 include
  • KiCad使用笔记(05)-PCB绘制

    文章目录 绘图过程 导入网表 绘制PCB边框 摆放元件 添加导线 交互式布线 添加铺铜 放置过孔 检测PCB 整理丝印 生成钻孔文件 生成光绘文件 相关视频教程 绘图过程 导入网表 绘制PCB边框 PCB边框放置在Edge Cuts层 可以
  • Java课题笔记~ SpringBoot简介

    1 入门案例 问题导入 SpringMVC的HelloWord程序大家还记得吗 SpringBoot是由Pivotal团队提供的全新框架 其设计目的是用来简化Spring应用的初始搭建以及开发过程 原生开发SpringMVC程序过程 1 1
  • useEffect实现数据请求刷新的几种方法

    请求数据入参变化的情况下重新请求数据的情景下useEffect的几种写法 1 函数在useEffect里面 const query useEffect gt function fetchData return https hn algoli
  • Redis-大key解决策略

    大key的定义 首先大key不是key很大而是key对应的value值很大 一般而言如果String类型值大于10KB Hash Set Zset List类型的元素的个数大于5000个都可以称之为大key 大key的危害 客户端超时等待
  • 通过示例学习 PyTorch

    通过示例学习 PyTorch 本教程通过独立的示例介绍 PyTorch 的基本概念 PyTorch 的核心是提供两个主要功能 n 维张量 类似于 numpy 但可以在 GPU 上运行 自动区分以构建和训练神经网络 我们将使用完全连接的 Re
  • 自动化测试的一些面试题分享

    一 Web自动化测试 1 Selenium中hidden或者是display none的元素是否可以定位到 不能 可以写JavaScript将标签中的hidden先改为0 再定位元素 2 Selenium中如何保证操作元素的成功率 也就是说
  • sqrt函数实现之卡马克方法

    sqrt函数的实现主要有三种方式 二分法 牛顿法 卡马克方法 卡马克方法 这里主要介绍高效的卡马克方法 卡马克方法起源于 雷神之锤III竞技场 中使用的平方根倒数速算法 下列代码是平方根倒数速算法在 雷神之锤III竞技场 源代码中的应用实例
  • HashSet中存储复杂类型对象

    这个话题还是从一个有问题的代码中引申出来的 原代码如下 import java util class TreeSetTest public static void main String args HashSet hs new HashSe
  • java 内存偏移量_如何计算静态变量的内存地址相对其Class对象内存地址的偏移量呢...

    我在一篇文章中看到这么一段话 我想验证一下 对于HotSpot VM的对象模型 静态字段的 偏移量 就是 JDK 6或之前 相对该类对应的InstanceKlass 实际上是包装InstanceKlass的klassOopDesc 对象起始
  • 关于32单片机时钟使能问题

    事实上 对于32单片机也好 51单片机也好 对于寄存器的操作 都是要进行使能时钟的 具体原因可以百度一下 只不过 51单片机就一个时钟系统 默认所有寄存器都是处于 开 状态 这样就加大了它的功耗 而32单片机寄存器很多 就必须 给每一组寄存
  • MyBatis-Plus复杂条件查询---Example

    目录 概要 Example 类的使用 1 导入依赖 2 创建 Example 对象 3 设置查询条件 4 设置排序规则 5 执行查询 6 分页查询 总结 概要 tk mybatis mapper entity Example 是 MyBat
  • 使用ViewPager+Fragment+仿网易云音乐的tab选项栏来实现多屏滑动

    ViewPager Fragment 仿网易云音乐的选项栏实现多屏滑动 效果图 工程 源码链接
  • C++中四种强制类型转换问题

    参考之前写的博客 C C 中强制类型的转换 static cast Littlehero 121的博客 CSDN博客 参考大神博客 C 中的强制类型转换 原野追逐 博客园 C 四种强制类型转换总结 详细介绍可以参考博客 C 四种强制类型转换
  • JPA主键生成策略介绍

    JPA主键生成策略 引言 1 依赖 2 GeneratedValue注解 2 1 主键生成策略 strategy 2 2 主键生成器 generator 3 GenerationType 3 1 GenerationType TABLE 3