JPA中建立实体时,须要声明实体的主键及其主键生成策略。咱们有一个实体类叫作Email,其主键上声明以下:数据库
@Id @Column(name = "EMAIL_ID") @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emailSeq") @SequenceGenerator(initialValue = 1, name = "emailSeq", sequenceName = "EMAIL_SEQUENCE") private long id;
咱们使用@GeneratedValue的strategry字段声明主键生成策略,generator声明主键生成器的名称,对应于同名的主键生成器@SequenceGenerator或者@TableGenerator。ide
与Hibernate不一样,JPA只提供四种主键生成器策略,分别介绍以下:spa
多数数据库支持IDENTITY列,数据库会在新行插入时自动给ID赋值,这也叫作ID自增加列,好比MySQL中能够在建立表时声明“AUTO_INCREMENT”, 就是一个ID子增加列:hibernate
CREATETABLE EMAIL{ ID BIGINT NOT NULL AUTO_INCREMENT, MESSAGE VARCHAR(255) NOT NULL, PRIMARY KEY(ID) }
JPA中IDENTITY类型的主键生成策略用法以下:code
@GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private long id;
因为主键由数据库自动插入,所以不须要额外的配置信息。orm
多数数据库支持IDENTITY策略:MySQL, SQL Server, DB2, Derby, Sybase, PostgreSQL。generator
Oracle不支持ID子增加列而是使用序列的机制生成主键ID,对此,能够选用序列做为主键生成策略:it
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emailSeq") @SequenceGenerator(initialValue = 1, name = "emailSeq", sequenceName = "EMAIL_SEQUENCE") private long id;;
上述声明等同于在数据库上建立一个序列:io
create sequence EMAIL_SEQUENCE;
若是不指定序列生成器的名称,则使用厂商提供的默认序列生成器,好比Hibernate默认提供的序列名称为hibernate_sequence。table
支持的数据库: Oracle、PostgreSQL、DB2
有时候为了避免依赖于数据库的具体实现,在不一样数据库之间更好的移植,能够在数据库中新建序列表来生成主键,序列表通常包含两个字段:第一个字段引用不 同的关系表,第二个字段是该关系表的最大序号。这样,只须要一张序列就能够用于多张表的主键生成。 用法:
@TableGenerator( name = "emailSeq", table = "MY_PROJECT_SEQUENCE_TABLE", pkColumnName = "SEQUENCE_NAME", valueColumnName = "SEQUENCE_COUNT", initialValue = 1, allocationSize = 1) @GeneratedValue( strategy = GenerationType.TABLE, generator = "emailSeq")
若是不指定表生成器,JPA厂商会使用默认的表,好比Hibernate在Oracle数据库上会默认使用表hibernate_sequence。
这种方式虽然通用性最好,全部的关系型数据库都支持,可是因为不能充分利用具体数据库的特性,建议不要优先使用。
把主键生成策略交给JPA厂商(Persistence Provider),由它根据具体的数据库选择合适的策略,能够是Table/Sequence/Identity中的一种。假如数据库是Oracle,则选择Sequence。
@GeneratedValue(strategy = GenerationType.AUTO)
若是不特别指定,这是默认的主键生成策略。