主键生成策略

本章节中将介绍 JPA 中主键生成策略,主键生成策略需要配合 @GeneratedValue 和 @Id 注解一起使用。

在一张表中,主键列的信息通常需要受到程序员的特殊关照。首先,我们需要在主键属性(即使用 @Id 注解修饰的属性)上使用 @GeneratedValue 注解中的 strategy 属性来设值主键的生成方式。

例如:使用 strategy 指定主键生成策略为 GenerationType.TABLE,代码如下:

@GeneratedValue(strategy = GenerationType.TABLE)
@Id
private Integer id;

其中,strategy 可取值如下:

  • GenerationType.AUTO

  • GenerationType.IDENTITY

  • GenerationType.TABLE

  • GenerationType.SEQUENCE

GenerationType.AUTO

把主键生成策略交给 JPA 厂商(Persistence Provider),由它根据具体的数据库选择合适的策略,可以是 Table/Sequence/Identity 中的一种。

假如数据库是 Oracle,则选择 Sequence;如果数据库是 MySQL,则选择 Identity;

注意:如果不做特别指定,JPA 默认是使用这种方式生成主键。

GenerationType.IDENTITY

多数数据库支持 IDENTITY,数据库会在新行插入时自动给 ID 赋值,这也叫做 ID 自增长列。例如 MySQL 中可以在创建表时声明 “AUTO_INCREMENT”,例如:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `age` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

注意:该策略在 Oracle 数据库中不支持

GenerationType.TABLE

有时候为了不依赖于数据库的具体实现,在不同数据库之间更好的移植,可以在数据库中新建序列表来生成主键,序列表一般包含两个字段:

  • 第一个字段引用不同的关系表

  • 第二个字段是该关系表的最大序号

这样,只需要一张序列就可以用于多张表的主键生成。如果不指定表生成器,JPA 厂商会使用默认的表。例如:

  • Hibernate 会默认使用 hibernate_sequence 表

  • OpenJPA 会默认使用 openjpa_sequence_table 表

这种方式虽然通用性最好,所有的关系型数据库都支持,但是由于不能充分利用具体数据库的特性,建议不要优先使用。

例如:OpenJPA 的 openjpa_sequence_table 表的 SQL 脚本如下:

CREATE TABLE `openjpa_sequence_table` (
  `ID` tinyint(4) NOT NULL,
  `SEQUENCE_VALUE` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

GenerationType.SEQUENCE

Oracle 不支持 ID 自增长列而是使用序列的机制生成主键 ID。对此,可以选用序列(Sequence)作为主键生成策略。

如果不指定序列生成器的名称,则使用厂商提供的默认序列生成器,比如 Hibernate 默认提供的序列名称为 hibernate_sequence。

支持的数据库:Oracle、PostgreSQL、DB2

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号