在讲主键策略之前首先简单介绍一下JPA。
JPA是一种java规范,而不是一种框架,而是一个ORM规范。JPA可以支持多种ORM框架,例如:hibernate,OpenJPA,TopLink,EclipseJPA等。JPA只是提供了统一的规范接口,最终实现由各个数据库厂商来实现。这样设计的目的是为了解决项目中切换ORM框架,数据库连接等所造成的成本。
我们在用JPA开发的时候,经常会在实体类的ID加上@GeneratedValue注解,用于生成表的主键。
例如:
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private String id;
其中:strategy用于生命主键生成策略,JPA提供了四种主键生成的策略。
1.GenerationType.IDENTITY
id自增长,数据库在新增一行数据的时候,自动给id赋值,类似于MySql新建表时,设计的列为auto_increment,常见的数据库基本上都支持该策略。
2.GenerationType.AUTO
自动从其他三种策略中选择主键生成的策略,将主键生成的策略交给JPA来处理,JPA会根据不同的数据库选择合适的策略。
3.GenerationType.SEQUENCE
使用序列的方式生成主键,例如:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "testSeq")
@SequenceGenerator(initialValue = 1,name = "testSeq", sequenceName = "TEST_SEQUENCE")
private String id;
以上声明相当于创建了一个序列,create sequence TEST_SEQUENCE;
如果不指定序列生成器的名称,则使用厂商提供的默认序列生成器,比如Hibernate默认提供的序列名称为hibernate_sequence。
4.GenerationType.TABLE
该策略利用数据库中的一个表来生成主键,可以不依赖于数据库的具体实现,可以实现在不同的数据库之间切换。
如果不指定表生成器,JPA厂商会使用默认的表,比如Hibernate在Oracle数据库上会默认使用表hibernate_sequence。
例子:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "testSeq")
@TableGenerator(name ="PK_SEQ",table="SEQUENCE_TABLE",pkColumnName="SEQUENCE_NAME", valueColumnName = "SEQUENCE_COUNT")
private String id;
name属性表示表生成器的名称,table表示用哪个表来存储生成的主键,pkColumnName用来指定生成器表中的那一列来存储主键,valueColumnName 指定生成器表中列是用来存储最后生成的那个主键的值。