必威体育Betway必威体育官网
当前位置:首页 > IT技术

[JavaEE] JPA中的Primary Key的几种生成方式

时间:2019-10-11 18:13:20来源:IT技术作者:seo实验室小编阅读:52次「手机版」
 

primarykey

本文发表在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/

相关阅读

身份证号码生成

Python 身份证号码生成 1、使用内置函数type(object)查看字符类型len_l = randint(0, 3019) print(len_l) line = open("xingzhen

抓取中国地震台网最近一年地震数据,生成表格以及地震分

代码如下: import requests from lxml import etree import pymysql from pyecharts import Geo import numpy as np earthquake

生成随机数(C语言,任意随机)

随机函数用于产生伪随机数,需要头文件stdlib.h。int rand()可以产生一个[0,RAND_MAX]范围内的伪随机数,其中RAND_MAX是一个系统定义

最小生成树(克鲁斯卡尔算法)

关于点击这里->普里姆算法 克鲁斯卡尔算法百度到的解释是:克鲁斯卡尔算法是一种用来寻找最小生成树的算法。在剩下的所有未选取的

订单号生成方法

package com.jae.impl;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;@Servicepub

分享到:

栏目导航

推荐阅读

热门阅读