JPA主键生成策略介绍

简介: 【1月更文挑战第9天】本篇 Huazie 向大家介绍 JPA主键生成策略

JPAplus.jpeg

引言

接入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 的主键生成器表介绍,敬请期待!!!

目录
相关文章
|
监控 微服务 Python
微服务的故障恢复与弹性设计
【8月更文第29天】在微服务架构中,由于服务间的相互依赖,任何单点故障都可能导致整个系统崩溃。因此,设计具备高可用性和弹性的微服务系统至关重要。本文将探讨如何通过重试机制、断路器和超时设置等策略来增强系统的容错能力和恢复能力。
492 1
产品经理-面试问题(实习)
这份文档主要讨论了实习面试中的常见问题,指出市面上的“面试100问”多针对C端产品,而B端和G端产品的面试则更注重实际工作经验。文中列举了几个典型的实习面试问题,如介绍实习经历、遇到的困难及解决方法、最佳项目以及竞争优势等,并提供了回答这些问题的思路和建议。文档还引导读者查阅更多相关资料,如高频分级面试和初级面试问题。
|
10月前
|
存储 缓存 前端开发
如何使用 CacheStorage 实现离线缓存
CacheStorage 是一种在客户端存储数据的 API,适用于 Service Worker。通过它,可以实现网页资源的离线缓存,提高应用加载速度和用户体验。使用时,先打开缓存,然后添加、获取或删除资源,确保应用即使在网络不可用时也能正常运行。
|
12月前
|
数据采集 JavaScript 前端开发
网页抓取进阶:如何提取复杂网页信息
在信息爆炸时代,从复杂网页中高效抓取数据对开发者和分析师至关重要。本文探讨如何利用 `webpage` 对象结合代理IP技术,轻松抓取如大众点评这类动态加载且具备反爬机制的网站数据。通过 Python 的 `requests`、`BeautifulSoup` 和 `Selenium`,结合代理IP,详细讲解了如何应对动态内容加载、反爬机制等问题,并提供了具体代码实现。通过这种方法,可以批量抓取商家信息,为数据分析提供支持。
1067 1
网页抓取进阶:如何提取复杂网页信息
|
搜索推荐 Java
简单而经典:Java中的冒泡排序算法详解
冒泡排序(Bubble Sort)是一种简单的排序算法,它通过多次遍历待排序的元素,比较相邻元素的大小,并交换它们直到整个序列有序。冒泡排序的基本思想是将较大的元素逐渐“浮”到数组的右端,而较小的元素逐渐“沉”到数组的左端。
1237 1
简单而经典:Java中的冒泡排序算法详解
|
消息中间件 存储 监控
消息中间件第八讲:消息队列 RocketMQ 版实战、集群及原理
消息中间件第八讲:消息队列 RocketMQ 版实战、集群及原理
655 0
|
供应链 Shell Python
经济订货量(Economic Order Quantity,简称EOQ)
经济订货量(Economic Order Quantity,简称EOQ)
|
算法 调度 决策智能
基于GA-PSO遗传粒子群混合优化算法的DVRP问题求解matlab仿真
该文介绍了车辆路径问题(VRP)的优化求解,特别是动态车辆路径问题(DVRP)。在MATLAB2022a中运用GA-PSO混合优化算法进行测试,展示了运行结果图像。核心程序包含粒子更新、交叉、距离计算等步骤。DVRP在物流配送、运输调度中有广泛应用,目标是最小化行驶距离并满足车辆容量限制。遗传算法通过选择、交叉和变异操作寻找解,而粒子群优化模拟鸟群行为更新速度和位置。GA-PSO混合算法结合两者优点,提高搜索效率。在DVRP中,算法需考虑问题特性和约束,以找到高质量解。
|
负载均衡 应用服务中间件 nginx
深入探索微服务架构中的服务发现机制
在当今微服务架构盛行的背景下,服务发现成为了保证系统高效运行的关键技术之一。本文将深入探讨服务发现的概念、重要性以及实现方式,通过对比不同服务发现机制的优劣,为读者提供在微服务架构设计中做出合理选择的参考。文章首先介绍了服务发现的基本概念和作用,随后详细分析了客户端发现和服务端发现两种主流机制,并以Eureka、Consul、Zookeeper等常见服务发现工具为例,展开讨论。最后,文章还探讨了服务发现在微服务架构中面临的挑战和未来发展趋势,旨在为微服务架构的设计和实施提供全面而深入的指导。
|
JavaScript IDE 开发工具
Windows环境检验NodeJs安装是否成功
Windows环境检验NodeJs安装是否成功
226 0