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)
|