[JavaEE] JPA中的Primary Key的几种生成方式
来源:互联网 发布:淘宝商家发货流程 编辑:程序博客网 时间:2024/06/09 18:46
本文发表在https://softwarecave.org/2014/08/02/primary-key-generators-in-jpa/,详实、易懂的介绍了JPA 的Key Generator
Generation of primary key values is a very important functionality of relational database management systems. The main idea is to let RDBMS automatically calculate and assign primary key value to the row being inserted into the database table. This not only simplifies the source code of the application using database but also makes the application more robust. There are two widely known methods to perform the generation of primary key values on the database level: auto-increment/identity columns or sequences.
Due to these differences JPA provide three different ways to automatically generate primary key values. Let’s explore them below.
1 Using auto-increment/identity columns
MySQL and Microsoft SQL Server provide a functionality to automatically generate a unique number for the primary key when a new row is added into a table. For example, in MySQL it is done by marking primary key column with AUTO_INCREMENT
keyword:
CREATE TABLE JPAGEN_ADDRESS( ID INT PRIMARY KEY AUTO_INCREMENT, CITY VARCHAR(255) NOT NULL, STREET VARCHAR(255) NOT NULL);
and in Microsoft SQL Server with IDENTITY
keyword:
CREATE TABLE JPAGEN_ADDRESS( ID INT IDENTITY(1,1) PRIMARY KEY, CITY VARCHAR(255) NOT NULL, STREET VARCHAR(255) NOT NULL);
JPA must be informed to use auto-increment/identity for primary key by specifying IDENTITY
generation strategy on the ID column:
@Entity@Table(name = "JPAGEN_ADDRESS")public class Address implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; // other fields and methods are omitted }
Now, when a new Address entity
is persisted, the value of the primary key column will be automatically generated by the database.
2 Using sequences
Oracle Database and PostgreSQL use explicit sequence type to generate unique primary key numbers. For example, in Oracle Database the table and its sequence can be defined like this:
CREATE TABLE JPAGEN_ADDRESS( ID NUMBER PRIMARY KEY, CITY VARCHAR(255) NOT NULL, STREET VARCHAR(255) NOT NULL);CREATE SEQUENCE JPAGEN_ADDRESS_SEQ START WITH 100;
When using sequence for given entity, the SEQUENCE
strategy must be defined on its ID column and additionally the name of the sequence must be specified using @SequenceGenerator
annotation:
@Entity@Table(name = "JPAGEN_ADDRESS")public class Address implements Serializable { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "addressGen") @SequenceGenerator(name = "addressGen", sequenceName = "JPAGEN_ADDRESS_SEQ") private long id; // other fields and methods are omitted }
When a new Address entity is persisted, JPA implementation will obtain the next value of the sequence and use it to insert a new row into the database table.
3 Using table
The third method to generate primary keys is to have a separate table which stores in a single row the sequence name along with the next number to use for the primary key. For performance reasons the next value is not increased by one, whenever JPA implementation needs a new value for the primary key but by a much higher number (e.g. 50). Once the range of values becomes reserved, JPA implementation can assign primary keys without accessing the database. When every value in the range becomes used, JPA implementation reserves a new range and the cycle continues.
Additionally, in such table we can have multiple rows with each row serving different entity. The only requirement is to use unique sequence names for each entity.
The table strategy is the most complicated one but it is the only strategy that is really portable across different databases. If you are developing an application which can use multiple RDBMS or there may be a need to port to a new RDBMS in the future, using table strategy is the most viable option.
The table to store the Person entity and the table to generate sequences can be created like this:
CREATE TABLE JPAGEN_PERSON( ID NUMBER PRIMARY KEY, NAME VARCHAR(255) NOT NULL, ADDRESS_ID NUMBER);CREATE TABLE JPAGEN_GENERATORS( NAME VARCHAR(255) PRIMARY KEY, VALUE NUMBER);
The table with sequences must have two columns. The first one should contain the name of the sequence and the second one should be of numeric type. JPA implementation will automatically update the second column when reserving a new range of values.
Additionally, JPA must be instructed to use TABLE generation strategy:
@Entity@Table(name = "JPAGEN_PERSON")public class Person implements Serializable { @Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "personGen") @TableGenerator(name = "personGen", table = "JPAGEN_GENERATORS", pkColumnName = "NAME", pkColumnValue = "JPAGEN_PERSON_GEN", valueColumnName = "VALUE") private long id; // other fields and methods are omitted }
We also have to add @TableGenerator
annotation to inform JPA about the name of the generator table (table element), the names of its both columns (pkColumnName and valueColumnName elements)
and also the name of the sequence (pkColumnValue element)
.
4 Conclusion
The choice between IDENTITY, SEQUENCE and TABLE strategies should be pretty obvious. If you application is going to use only one RDBMS, the first or the second option should be fine (depending on your RDBMS vendor). In other cases, TABLE strategy is preferred, if not the only possible.
5 Reference
[1] https://softwarecave.org/2014/08/02/primary-key-generators-in-jpa/
- [JavaEE] JPA中的Primary Key的几种生成方式
- JavaEE调试的几种方式
- [JavaEE - JPA] 5. ORM的核心注解 - 访问方式,表映射以及主键生成
- [JavaEE - JPA] 5. ORM的核心注解 - 访问方式,表映射以及主键生成
- about JPA persistence of primary key(多主鍵)
- 生成Surrogate Key的几种方案
- JDBC获得数据库生成的主键(JDBC、Primary Key)
- javaee前后台之间传值的几种方式
- 【JavaEE】读取配置文件路径的几种方式
- key,primary key unique key的区别
- JavaEE – JPA(5):ORM的核心注解 – 访问方式,表映射以及主键生成
- JavaEE – JPA(4):ORM的核心注解 – 访问方式,表映射以及主键生成
- [JavaEE - JPA] 性能优化: 4种触发懒加载的方式
- candidate key, primary key, superkey的区别
- Unique Key 与 Primary Key 的比较
- MySql 的unique key 与 primary key
- Unique Key 与 Primary Key 的比较
- PRIMARY KEY 与 UNIQUE KEY 的区别
- jsp页面截取值操作方式
- java并发机制
- Linux中find常见用法
- mysql知识点
- MFC连接access制作登录界面
- [JavaEE] JPA中的Primary Key的几种生成方式
- HDU1069(DAG)
- 离散题目5
- Java float型数据判断是否相等
- Tomcat数据库连接池的配置方法总结
- SDUT 3805 离散题目11
- 读书的作用--引用《儒道至圣》小说章节
- JS中的caller属性
- VC中#pragma小结