JPA实体注解与hibernate主键生成策略
JPA實體注解與hibernate主鍵生成策略
???用hibernate注解開發項目,對于主鍵的生成策略有些模糊,下面是從新浪網里面看到的一篇關于hibernate注解以及主鍵生成策略的文章,值得一看:
??
1. 實體標志:
????@Entity
?????@Indexed(index="group")
?????@Table(name="GROUP_LAYMOD")
????* @Indexed 標識需要進行索引的對象,
????* 屬性 : index 指定索引文件的路徑 @DocumentId 用于標示實體類中的唯一的屬性保存在索引文件中,是當進行全文檢索時可以這個唯一的屬性來區分索引中其他實體對象,一般使用實體類中的主鍵屬性
????* @Field 標注在類的get屬性上,標識一個索引的Field
??????屬性 : index 指定是否索引,與Lucene相同
??????store 指定是否索引,與Lucene相同
??????name 指定Field的name,默認為類屬性的名稱
??????analyzer 指定分析器
在hibernate注解主鍵的時候,一般會使用到這兩個。
??@GeneratedValue的作用是JPA的默認實現自定義主鍵生成策略
???@GenericGenerator是hibernate在JPA的基礎上增強。
自定義主鍵生成策略,由@GenericGenerator實現。
hibernate在JPA的基礎上進行了擴展,可以用一下方式引入hibernate獨有的主鍵生成策略,就是通過@GenericGenerator加入的。
比如說,JPA標準用法
@Id??
@GeneratedValue(GenerationType.AUTO)??
就可以用hibernate特有以下用法來實現
@GeneratedValue(generator?=?"paymentableGenerator")?????
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"assigned")??
@GenericGenerator的定義:
@Target({PACKAGE,?TYPE,?METHOD,?FIELD})???
@Retention(RUNTIME)???
public?@interface?GenericGenerator?{???
??
String?name();???
??
String?strategy();???
??
Parameter[]?parameters()?default?{};???
}??
name屬性指定生成器名稱。
strategy屬性指定具體生成器的類名。
parameters得到strategy指定的具體生成器所用到的參數。
對于這些hibernate主鍵生成策略和各自的具體生成器之間的關系,在org.hibernate.id.IdentifierGeneratorFactory中指定了,
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一共默認支持十三種生成策略。
1、native
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")?????
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"native")???
2、uuid
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")?????
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"uuid")???
3、hilo
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")?????
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"hilo")???
4、assigned
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")?????
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"assigned")???
5、identity
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")?????
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"identity")???
6、select
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")???
@GenericGenerator(name="select",?strategy="select",???
??????parameters?=?{?@Parameter(name?=?"key",?value?=?"idstoerung")?})??
7、sequence
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")???
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"sequence",???
??????????parameters?=?{?@Parameter(name?=?"sequence",?value?=?"seq_payablemoney")?})??
8、seqhilo
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")???
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"seqhilo",???
??????????parameters?=?{?@Parameter(name?=?"max_lo",?value?=?"5")?})??
9、increment
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")?????
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"increment")???
10、foreign
Java代碼
@GeneratedValue(generator?=?"idGenerator")???
@GenericGenerator(name?=?"idGenerator",?strategy?=?"foreign",???
??????????parameters?=?{?@Parameter(name?=?"property",?value?=?"employee")?})??
注意:直接使用@PrimaryKeyJoinColumn?報錯(?)
Java代碼
@OneToOne(cascade?=?CascadeType.ALL)???
@PrimaryKeyJoinColumn???
例如
Java代碼
@Entity??
public?class?Employee?{???
??@Id?Integer?id;???
???????
??@OneToOne?@PrimaryKeyJoinColumn??
???EmployeeInfo?info;???
??????
}??
應該為
Java代碼
@Entity??
public?class?Employee?{???
??@Id???
??@GeneratedValue(generator?=?"idGenerator")???
??@GenericGenerator(name?=?"idGenerator",?strategy?=?"foreign",???
??????????parameters?=?{?@Parameter(name?=?"property",?value?=?"info")?})???
???Integer?id;???
???????
??@OneToOne??
???EmployeeInfo?info;???
??????
}??
11、guid
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")?????
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"guid")???
12、uuid.hex
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")?????
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"uuid.hex")???
13、sequence-identity
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")???
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"sequence-identity",???
??????????parameters?=?{?@Parameter(name?=?"sequence",?value?=?"seq_payablemoney")?})??
四、通過@GenericGenerator自定義主鍵生成策略
如果實際應用中,主鍵策略為程序指定了就用程序指定的主鍵(assigned),沒有指定就從sequence中取。
明顯上面所討論的策略都不滿足,只好自己擴展了,集成assigned和sequence兩種策略。
Java代碼
public?class?AssignedSequenceGenerator?extends?SequenceGenerator?implements???
PersistentIdentifierGenerator,?Configurable?{???
private?String?entityName;???
?????
public?void?configure(Type?type,?Properties?params,?Dialect?dialect)?throws?MappingException?{???
???entityName?=?params.getProperty(ENTITY_NAME);???
??if?(entityName==null)?{???
???throw?new?MappingException("no?entity?name");???
???}???
?????
??super.configure(type,?params,?dialect);?????
}???
??
public?Serializable?generate(SessionImplementor?session,?Object?obj)???
??throws?HibernateException?{???
?????
???Serializable?id?=?session.getEntityPersister(?entityName,?obj?)???
?????.getIdentifier(?obj,?session.getEntityMode()?);???
?????
??if?(id==null)?{???
????id?=?super.generate(session,?obj);???
???}???
?????
??return?id;???
}???
}??
實際應用中,定義同sequence。
Java代碼
@GeneratedValue(generator?=?"paymentableGenerator")???
@GenericGenerator(name?=?"paymentableGenerator",?strategy?=?"AssignedSequenceGenerator",???
??????parameters?=?{?@Parameter(name?=?"sequence",?value?=?"seq_payablemoney")?})??
值得注意的是,定義的這種策略,就像打開了潘多拉魔盒,非常不可控。正常情況下,不建議這么做。
策略解釋
?“assigned”?
??主鍵由外部程序負責生成,在???save()???之前指定一個。?
??“hilo”?
??通過hi/lo???算法實現的主鍵生成機制,需要額外的數據庫表或字段提供高位值來源 ???
??“seqhilo”?
??與hilo???類似,通過hi/lo???算法實現的主鍵生成機制,需要數據庫中的???Sequence,適用于支持??Sequence???的數據庫,如Oracle。?
??
??“increment”?
??主鍵按數值順序遞增。此方式的實現機制為在當前應用實例中維持一個變量,以保存著當前的最大值,之后每次需要生成主鍵的時候將此值加1作為主鍵。這種方式可能產生的問題是:不能在集群下使用。???
??“identity”?
??采用數據庫提供的主鍵生成機制。如DB2、SQL???Server、MySQL???中的主鍵生成機制。?
??“sequence”?
??采用數據庫提供的???sequence???機制生成主鍵。如???Oralce???中的Sequence。?
??“native”?
??由???Hibernate??根據使用的數據庫自行判斷采用???identity、hilo、sequence???其中一種作為主鍵生成方式。???
??“uuid.hex”?
??由???Hibernate???基于128???位???UUID???算法???生成16???進制數值(編碼后以長度32???的字符串表示)作為主鍵。?
??“uuid.string”?
??與uuid.hex???類似,只是生成的主鍵未進行編碼(長度16),不能應用在???PostgreSQL???數據庫中。?
??“foreign”?
??使用另外一個相關聯的對象的標識符作為主鍵。
總結
以上是生活随笔為你收集整理的JPA实体注解与hibernate主键生成策略的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android2.2 r1 API 中文
- 下一篇: SVN修改用户名与密码