理解JPA注解@GeneratedValue的使用方法


https://blog.csdn.net/u012838207/article/details/80406716

一、JPA通用策略生成器

通過annotation來映射hibernate實體的,基於annotation的hibernate主鍵標識為@Id,

其生成規則由@GeneratedValue設定的.這里的@id和@GeneratedValue都是JPA的標准用法,

JPA提供四種標准用法,由@GeneratedValue的源代碼可以明顯看出.

?
1
2
3
4
5
6
Target({METHOD,FIELD}) 
   @Retention (RUNTIME) 
   public @interface GeneratedValue{ 
     GenerationType strategy() default AUTO; 
     String generator() default ""
   }

其中GenerationType:

?
1
2
3
4
5
6
public enum GenerationType{ 
   TABLE, 
   SEQUENCE, 
   IDENTITY, 
   AUTO 
}

JPA提供的四種標准用法為TABLE,SEQUENCE,IDENTITY,AUTO.

  • TABLE:使用一個特定的數據庫表格來保存主鍵。
  • SEQUENCE:根據底層數據庫的序列來生成主鍵,條件是數據庫支持序列。
  • IDENTITY:主鍵由數據庫自動生成(主要是自動增長型)
  • AUTO:主鍵由程序控制。

TABLE比較復雜,這里不講解。分別介紹其他三個:

1.SEQUENCE

實體類中的注解

?
1
2
3
@Id
@GeneratedValue (strategy =GenerationType.SEQUENCE,generator= "aaa" )
@SequenceGenerator (name= "aaa" , sequenceName= "seq_payment" )

@SequenceGenerator定義

?
1
2
3
4
5
6
7
8
@Target ({TYPE, METHOD, FIELD}) 
@Retention (RUNTIME)
public @interface SequenceGenerator {
  String name();
  String sequenceName() default "" ;
  int initialValue() default 0 ;
  int allocationSize() default 50 ;
}
  • name屬性表示該表主鍵生成策略的名稱,它被引用在@GeneratedValue中設置的“generator”值中。
  • sequenceName屬性表示生成策略用到的數據庫序列名稱。
  • initialValue表示主鍵初識值,默認為0。
  • allocationSize表示每次主鍵值增加的大小,例如設置成1,則表示每次創建新記錄后自動加1,默認為50。

2.IDENTITY

主鍵則由數據庫自動維護,使用起來很簡單

?
1
2
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)

3、AUTO

默認的配置。如果不指定主鍵生成策略,默認為AUTO。

?
1
2
@Id
@GeneratedValue (strategy = GenerationType.AUTO)

二、hibernate主鍵策略生成器

hibernate提供多種主鍵生成策略,有點是類似於JPA,有的是hibernate特有,下面列出幾個Hibernate比較常用的生成策略:

  • native: 對於 oracle 采用 Sequence 方式,對於MySQL 和 SQL Server 采用identity(自增主鍵生成機制),native就是將主鍵的生成工作交由數據庫完成,hibernate不管
  • uuid: 采用128位的uuid算法生成主鍵,uuid被編碼為一個32位16進制數字的字符串。占用空間大(字符串類型)。
  • assigned: 在插入數據的時候主鍵由程序處理(即程序員手動指定),這是 <generator>元素沒有指定時的默認生成策略。等同於JPA中的AUTO。
  • identity: 使用SQL Server 和 MySQL 的自增字段,這個方法不能放到 Oracle 中,Oracle 不支持自增字段,要設定sequence(MySQL 和 SQL Server 中很常用)。 等同於JPA中的INDENTITY。
  • increment: 插入數據的時候hibernate會給主鍵添加一個自增的主鍵,但是一個hibernate實例就維護一個計數器,所以在多個實例運行的時候不能使用這個方法。

hibernate提供了多種生成器供選擇,基於Annotation的方式通過@GenericGenerator實現.

hibernate每種主鍵生成策略提供接口org.hibernate.id.IdentifierGenerator的實現類,如果要實現自定義的主鍵生成策略也必須實現此接口.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface IdentifierGenerator {
   /**
    * The configuration parameter holding the entity name
    */
   public static final String ENTITY_NAME = "entity_name" ;
 
  /**
   * Generate a new identifier.
   * @param session
   * @param object the entity or toplevel collection for which the id is being generated
   *
   * @return a new identifier
   * @throws HibernateException
   */
  public Serializable generate(SessionImplementor session, Object object) 
   throws HibernateException;
}

IdentifierGenerator提供一generate方法,generate方法返回產生的主鍵.

三、@GenericGenerator

自定義主鍵生成策略,由@GenericGenerator實現。

hibernate在JPA的基礎上進行了擴展,可以用一下方式引入hibernate獨有的主鍵生成策略,就是通過@GenericGenerator加入的。

比如說,JPA標准用法

?
1
2
@Id
@GeneratedValue (GenerationType.AUTO)

就可以用hibernate特有以下用法來代替:

?
1
2
3
@Id
@GeneratedValue (generator = "paymentableGenerator"
@GenericGenerator (name = "paymentableGenerator" , strategy = "assigned" )

@GenericGenerator的定義:

?
1
2
@Target ({PACKAGE, TYPE, METHOD, FIELD})
@Retention (RUNTIME)

源代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public @interface GenericGenerator {
  /**
  * unique generator name
  */
  String name();
  /**
  * Generator strategy either a predefined Hibernate
  * strategy or a fully qualified class name.
  */
  String strategy();
  /**
  * Optional generator parameters
  */
  Parameter[] parameters() default {};
}
  • name屬性指定生成器名稱。
  • strategy屬性指定具體生成器的類名。
  • parameters得到strategy指定的具體生成器所用到的參數。

對於這些hibernate主鍵生成策略和各自的具體生成器之間的關系,在org.hibernate.id.IdentifierGeneratorFactory中指定了,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
static {
  GENERATORS.put( "uuid" , UUIDHexGenerator. class );
  GENERATORS.put( "hilo" , TableHiLoGenerator. class );
  GENERATORS.put( "assigned" , Assigned. class );
  GENERATORS.put( "identity" , IdentityGenerator. class );
  GENERATORS.put( "select" , SelectGenerator. class );
  GENERATORS.put( "sequence" , SequenceGenerator. class );
  GENERATORS.put( "seqhilo" , SequenceHiLoGenerator. class );
  GENERATORS.put( "increment" , IncrementGenerator. class );
  GENERATORS.put( "foreign" , ForeignGenerator. class );
  GENERATORS.put( "guid" , GUIDGenerator. class );
  GENERATORS.put( "uuid.hex" , UUIDHexGenerator. class ); //uuid.hex is deprecated
  GENERATORS.put( "sequence-identity" , SequenceIdentityGenerator. class );
}

上面十二種策略,加上native,hibernate一共默認支持十三種生成策略。使用hibernate注解示例如下:

?
1
2
3
@Id
@GeneratedValue (generator = "IDGenerator" )
@GenericGenerator (name = "IDGenerator" , strategy = "identity" )

這種完全類似於:

?

 

1
2
@Id
@GeneratedValue (strategy=GenerationType.IDENTITY)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM