JPA ID生成策略
資料的唯一性是很平常的要求,但是如果框架不能提供相關的控制而由程式設計師完全控制是很危險的,在JPA中,有下面四種策略。
A.容器自動生成---GeneratorType.AUTO
由JPA自動生成
B.使用資料庫的自動增長欄位生成---GenerationType.IDENTITY
JPA 容器將使用資料庫的自增長欄位為新增加的實體物件賦唯一值。這種情況下需要資料庫提供對自增長欄位的支援,SQL Server、MySQL、DB2、Derby等支援。
C.根據資料庫序列號(Sequence)生成 ---GenerationType.SEQUENCE
表示使用資料庫的序列號為新增加的實體物件賦唯一值。這種情況下需要資料庫提供對序列號的支援常用的資料庫中,Oracle支援。
D.使用資料庫表的欄位生成---GenerationType.TABLE
表示使用資料庫中指定表的某個欄位記錄實體物件的標識,通過該欄位的增長為新增加的實體物件賦唯一值
比較特殊的地方
1. 使用UUID(兩個不同實現版本Hibernate和OpenJPA有點不同)
OpenJPA
@GeneratedValue(strategy=GenerationType.AUTO, generator = "uuid")
Hibernate(Eclipse會提示錯誤,但是程式是可以執行的)
@GenericGenerator(name = "test", strategy = "uuid")
@GeneratedValue(generator = "test")
其實這兩種辦法我感覺都不是特別好,因為他們跟實現有關係,將來如果要遷移的話會比較麻煩,所以可以直接用java.util.UUID
user.setUserId(UUID.randomUUID().toString());
2.使用@GeneratedValue(strategy=GenerationType.IDENTITY)
需要在資料庫(Derby)中這樣定義欄位
USER_ID BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1)
3.如果使用資料庫表的欄位生成---GenerationType.TABLE
對於Hibernate,需要建立生成主鍵的表,但是OpenJPA不需要,如果沒有會自動生成。
程式碼如下:
@TableGenerator(name = "test111", table = "IDTABLE",
pkColumnName = "KEYID", valueColumnName = "KEYVALUE", pkColumnValue = "TestUSER_ID")
@GeneratedValue(strategy=GenerationType.TABLE, generator="test111")
CREATE TABLE IDTABLE (
KEYID VARCHAR(255) NOT NULL,
KEYVALUE BIGINT,
PRIMARY KEY (KEYID)
)