JPA主鍵生成器和主鍵生成策略

JPA中建立實體時,須要聲明實體的主鍵及其主鍵生成策略。咱們有一個實體類叫作Email,其主鍵上聲明以下:數據庫

 

@Id
@Column(name = "EMAIL_ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emailSeq")
@SequenceGenerator(initialValue = 1, name = "emailSeq", sequenceName = "EMAIL_SEQUENCE")
private long id;

 

咱們使用@GeneratedValue的strategry字段聲明主鍵生成策略,generator聲明主鍵生成器的名稱,對應於同名的主鍵生成器@SequenceGenerator或者@TableGenerator。ide

與Hibernate不一樣,JPA只提供四種主鍵生成器策略,分別介紹以下:spa

GenerationType.IDENTITY

多數數據庫支持IDENTITY列,數據庫會在新行插入時自動給ID賦值,這也叫作ID自增加列,好比MySQL中能夠在建立表時聲明「AUTO_INCREMENT」, 就是一個ID子增加列:hibernate

CREATETABLE EMAIL{
    ID BIGINT NOT NULL AUTO_INCREMENT, 
    MESSAGE VARCHAR(255) NOT NULL, 
    PRIMARY KEY(ID)
    }

JPA中IDENTITY類型的主鍵生成策略用法以下:code

 

@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private long id;

 

因爲主鍵由數據庫自動插入,所以不須要額外的配置信息。orm

多數數據庫支持IDENTITY策略:MySQL, SQL Server, DB2, Derby, Sybase, PostgreSQL。generator

GenerationType.SEQUENCE

Oracle不支持ID子增加列而是使用序列的機制生成主鍵ID,對此,能夠選用序列做爲主鍵生成策略:it

 

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emailSeq")
@SequenceGenerator(initialValue = 1, name = "emailSeq", sequenceName = "EMAIL_SEQUENCE")
private long id;;

 

上述聲明等同於在數據庫上建立一個序列:io

create sequence EMAIL_SEQUENCE;

若是不指定序列生成器的名稱,則使用廠商提供的默認序列生成器,好比Hibernate默認提供的序列名稱爲hibernate_sequence。table

支持的數據庫: Oracle、PostgreSQL、DB2

GenerationType.TABLE

有時候爲了避免依賴於數據庫的具體實現,在不一樣數據庫之間更好的移植,能夠在數據庫中新建序列表來生成主鍵,序列表通常包含兩個字段:第一個字段引用不 同的關係表,第二個字段是該關係表的最大序號。這樣,只須要一張序列就能夠用於多張表的主鍵生成。 用法:

 

@TableGenerator( name = "emailSeq", table = "MY_PROJECT_SEQUENCE_TABLE", pkColumnName = "SEQUENCE_NAME", valueColumnName = "SEQUENCE_COUNT", initialValue = 1, allocationSize = 1)
@GeneratedValue( strategy = GenerationType.TABLE, generator = "emailSeq")

 

若是不指定表生成器,JPA廠商會使用默認的表,好比Hibernate在Oracle數據庫上會默認使用表hibernate_sequence。

這種方式雖然通用性最好,全部的關係型數據庫都支持,可是因爲不能充分利用具體數據庫的特性,建議不要優先使用。

GenerationType.Auto

把主鍵生成策略交給JPA廠商(Persistence Provider),由它根據具體的數據庫選擇合適的策略,能夠是Table/Sequence/Identity中的一種。假如數據庫是Oracle,則選擇Sequence。

 

@GeneratedValue(strategy = GenerationType.AUTO)

 

若是不特別指定,這是默認的主鍵生成策略。

相關文章
相關標籤/搜索