JPA要求每個實體必須有且只有一個主鍵,而@GeneratedValue提供了主鍵的生成策略,這就是@GeneratedValue註解存在的意義。本文將淺析@GeneratedValue的源碼。php
@GeneratedValue的源碼以下:html
/* * Copyright (c) 2008, 2009, 2011 Oracle, Inc. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. The Eclipse Public License is available * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License * is available at http://www.eclipse.org/org/documents/edl-v10.php. */ package javax.persistence; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static javax.persistence.GenerationType.AUTO; /** * Provides for the specification of generation strategies for the * values of primary keys. * * <p> The <code>GeneratedValue</code> annotation * may be applied to a primary key property or field of an entity or * mapped superclass in conjunction with the {@link Id} annotation. * The use of the <code>GeneratedValue</code> annotation is only * required to be supported for simple primary keys. Use of the * <code>GeneratedValue</code> annotation is not supported for derived * primary keys. * * <pre> * * Example 1: * * @Id * @GeneratedValue(strategy=SEQUENCE, generator="CUST_SEQ") * @Column(name="CUST_ID") * public Long getId() { return id; } * * Example 2: * * @Id * @GeneratedValue(strategy=TABLE, generator="CUST_GEN") * @Column(name="CUST_ID") * Long id; * </pre> * * @see Id * @see TableGenerator * @see SequenceGenerator * * @since Java Persistence 1.0 */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface GeneratedValue { /** * (Optional) The primary key generation strategy * that the persistence provider must use to * generate the annotated entity primary key. */ GenerationType strategy() default AUTO; /** * (Optional) The name of the primary key generator * to use as specified in the {@link SequenceGenerator} * or {@link TableGenerator} annotation. * <p> Defaults to the id generator supplied by persistence provider. */ String generator() default ""; }
@Target({METHOD, FIELD})說明該註解能夠用於方法聲明和域聲明。java
@Retention(RUNTIME)說明該註解在VM運行期間也能夠保留,能夠經過反射機制讀取註解的信息。數據庫
若是不是很清楚,可參考@Controller和@Restcontroller源碼解析中有對元註解的介紹。app
@GeneratedValue註解有兩個屬性,分別是strategy和generator,其中generator屬性的值是一個字符串,默認爲"",其聲明瞭主鍵生成器的名稱。eclipse
查看GenerationType的源碼,能夠看到定義了四種主鍵生成策略:TABLE,SEQUENCE,IDENTITY,AUTO。ide
/* * Copyright (c) 2008, 2009, 2011 Oracle, Inc. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. The Eclipse Public License is available * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License * is available at http://www.eclipse.org/org/documents/edl-v10.php. */ package javax.persistence; /** * Defines the types of primary key generation strategies. * * @see GeneratedValue * * @since Java Persistence 1.0 */ public enum GenerationType { /** * Indicates that the persistence provider must assign * primary keys for the entity using an underlying * database table to ensure uniqueness. */ TABLE, /** * Indicates that the persistence provider must assign * primary keys for the entity using a database sequence. */ SEQUENCE, /** * Indicates that the persistence provider must assign * primary keys for the entity using a database identity column. */ IDENTITY, /** * Indicates that the persistence provider should pick an * appropriate strategy for the particular database. The * <code>AUTO</code> generation strategy may expect a database * resource to exist, or it may attempt to create one. A vendor * may provide documentation on how to create such resources * in the event that it does not support schema generation * or cannot create the schema resource at runtime. */ AUTO }
TABLEui
使用數據庫表來生成主鍵。該策略通常與另一個註解一塊兒使用@TableGenerator,@TableGenerator註解指定了生成主鍵的表(能夠在實體類上指定也能夠在主鍵字段或屬性上指定),而後JPA將會根據註解內容自動生成一張表做爲序列表(或使用現有的序列表)。若是不指定序列表,則會生成一張默認的序列表,表中的列名也是自動生成,數據庫上會生成一張名爲sequence的表(SEQ_NAME,SEQ_COUNT)。序列表通常只包含兩個字段:第一個字段是該生成策略的名稱,第二個字段是該關係表的最大序號,它會隨着數據的插入逐漸累加。該策略的好處就是不依賴於外部環境和數據庫的具體實現,便於移植;但因爲其不能充分利用數據庫的特性,因此不會優先使用。this
@Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "roleSeq") @TableGenerator(name = "roleSeq", allocationSize = 1, table = "seq_table", pkColumnName = "seq_id", valueColumnName = "seq_count") private Long id;
SEQUENCEspa
使用序列來生成主鍵。 該策略的不足之處正好與TABLE相反,因爲只有部分數據庫(Oracle,PostgreSQL,DB2)支持序列對象,因此該策略通常不該用於其餘數據庫。須要注意,MySQL不支持這種主鍵生成策略。該策略通常與另一個註解一塊兒使用@SequenceGenerator,@SequenceGenerator註解指定了生成主鍵的序列.而後JPA會根據註解內容建立一個序列(或使用一個現有的序列)。若是不指定序列,則會自動生成一個序列SEQ_GEN_SEQUENCE。
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "menuSeq") @SequenceGenerator(name = "menuSeq", initialValue = 1, allocationSize = 1, sequenceName = "MENU_SEQUENCE") private Long id;
IDENTITY
使用數據庫ID自增加的方式來生成主鍵。 該策略在大部分數據庫中都提供了支持(指定方法或關鍵字可能不一樣),但仍是有少數數據庫(Oracle)不支持,因此可移植性略差。
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
AUTO
自動選擇合適的主鍵生成策略。該策略比較經常使用,也是默認選項,@GeneratedValue(strategy = GenerationType.AUTO)至關於@GeneratedValue。
@Id @GeneratedValue private Long id;
參考:JPA之@GeneratedValue註解。這篇介紹的挺詳細的,推薦一下。