楔子
最近想把UUID32位的主键策略改为6位的INT自增的主键,来改善个人网站的优雅和简洁性。于是找了些资料整理在这。由于我的网站用的注解,来减少xml配置文件带来的烦躁,所以主键策略一定要是基于注解的。
一. 自定义主键生成策略,由@GenericGenerator实现。**
hibernate在JPA的基础上进行了扩展,可以用一下方式引入hibernate独有的主键生成策略,就是通过@GenericGenerator加入的。**
比如说,JPA标准用法**1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@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中指定了,
1 |
|
二. 上面十二种策略,加上native,hibernate一共默认支持十三种生成策略。
1、native
1 | @GeneratedValue(generator = "paymentableGenerator") |
2、uuid
1 | @GeneratedValue(generator = "paymentableGenerator") |
3、hilo
1 | @GeneratedValue(generator = "paymentableGenerator") |
4、assigned
1 | @GeneratedValue(generator = "paymentableGenerator") |
5、identity
1 | @GeneratedValue(generator = "paymentableGenerator") |
6、select
1 | @GeneratedValue(generator = "paymentableGenerator") |
7、sequence
1 | @GeneratedValue(generator = "paymentableGenerator") |
8、seqhilo
1 | @GeneratedValue(generator = "paymentableGenerator") |
9、increment
1 | @GeneratedValue(generator = "paymentableGenerator") |
10、foreign
1 | @GeneratedValue(generator = "idGenerator") |
@GeneratedValue(generator = “paymentableGenerator”)
@GenericGenerator(name = “paymentableGenerator”, strategy = “guid”)1
## 12、uuid.hex
@GeneratedValue(generator = “paymentableGenerator”)
@GenericGenerator(name = “paymentableGenerator”, strategy = “uuid.hex”)1
2
## 13、sequence-identity
@GeneratedValue(generator = “paymentableGenerator”)
@GenericGenerator(name = “paymentableGenerator”, strategy = “sequence-identity”,
parameters = { @Parameter(name = “sequence”, value = “seq_payablemoney”) })
1 | # 三、通过@GenericGenerator自定义主键生成策略 |
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;
}
}1
实际应用中,定义同sequence。
@GeneratedValue(generator = “paymentableGenerator”)
@GenericGenerator(name = “paymentableGenerator”, strategy = “AssignedSequenceGenerator”,
parameters = { @Parameter(name = “sequence”, value = “seq_payablemoney”) })
1 | 值得注意的是,定义的这种策略,就像打开了潘多拉魔盒,非常不可控。正常情况下,不建议这么做。 |
设置自增长主键的初始值
1 | alter table test AUTO_INCREMENT = 500000; |