博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JPA主键生成策略
阅读量:4180 次
发布时间:2019-05-26

本文共 4699 字,大约阅读时间需要 15 分钟。

JPA四种策略

  • TABLE:使用一个特定的数据库表格来保存主键。
  • SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
  • IDENTITY:主键由数据库自动生成(主要是自动增长型)
  • AUTO:主键由程序控制。 

 

@GeneratedValue的源码,默认是AUTO方式

@Target({ElementType.METHOD, ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface GeneratedValue {    GenerationType strategy() default GenerationType.AUTO;    String generator() default "";}

 

public enum GenerationType {    TABLE,    SEQUENCE,    IDENTITY,    AUTO;    private GenerationType() {    }}

 

Sequence 策略

一些数据库,比如 Oralce,有一种内置的叫做“序列” (sequence)的机制来生成主键。为了调用这个序列,需要使用 @javax.persistence.SequenceGenerator 这个注解。

 

@Entity public class PK_Sequence implements Serializable {    private static final long serialVersionUID = 1L;    @SequenceGenerator(name="PK_SEQ_TBL",sequenceName="PK_SEQ_NAME")    @Id    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator="PK_SEQ_TBL")    private Long id; // Getters and Setters }

 

@SequenceGenerator 注解的定义

@Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Retention(value = RetentionPolicy.RUNTIME) public @interface SequenceGenerator {     public String name();     public String sequenceName() default "";     public String catalog() default "";     public String schema() default "";     public int initialValue() default 1;     public int allocationSize() default 50; }

从定义中可以看出这个注解可以用在类上,也可以用在方法和字段上,其中 name 属性指定的是所使用的生成器;sequenceName 指定的是数据库中的序列;initialValue 指定的是序列的初始值,和 @TableGenerator 不同是它的缺省值 1;allocationSize 指定的是持久化引擎 (persistence engine) 从序列 (sequence) 中读取值时的缓存大小,它的缺省值是 50。

 

Identity 策略

一些数据库,如mysql,sqlserver用一个 Identity 列来生成主键,使用这个策略生成主键的时候,只需要在 @GeneratedValue 中用 strategy 属性指定即可。如下所示:

@Entity public class PK_Identity implements Serializable {    private static final long serialVersionUID = 1L;    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id; // Getters and Setters }

 

Auto 策略

使用 AUTO 策略就是将主键生成的策略交给持久化引擎 (persistence engine) 来决定,由它自己选择从 Table 策略,Sequence 策略和 Identity 策略三种策略中选择合适的主键生成策略。不同的持久化引擎 (persistence engine) 使用不同的策略,在 galss fish 中使用的是 Table 策略。

@Entity public class PK_Auto implements Serializable {    private static final long serialVersionUID = 1L;    @Id    @GeneratedValue(strategy = GenerationType.AUTO)    private Long id;    // Getters and Setters    }

或则只使用:

@Generated Value

或者干脆什么都不写,因为缺省得主键生成策略就是 AUTO。

 

Table 策略 (Table strategy)

这种策略中,持久化引擎 (persistence engine) 使用关系型数据库中的一个表 (Table) 来生成主键。这种策略可移植性比较好,因为所有的关系型数据库都支持这种策略。不同的 J2EE 应用服务器使用不同的持久化引擎。

下面用一个例子来说明这种表生成策略的使用:

@Entity  public class PrimaryKey_Table {   @TableGenerator(name = "PK_SEQ",  table = "SEQUENCE_TABLE",                 pkColumnName  = "SEQUENCE_NAME",                 valueColumnName  = "SEQUENCE_COUNT")   @Id     @GeneratedValue(strategy =GenerationType.TABLE,generator="PK_SEQ")     private Long id;   //Getters and Setters //为了方便,类里面除了一个必需的主键列,没有任何其他列,以后类似              }

 

首先,上面使用 @javax.persistence.TableGenerator 这个注解来指定一个用来生成主键的表 (Table),这个注解可以使用在实体类上,也可以像这个例子一样使用在主键字段上。

其中,在这个例子中,name 属性“PK_SEQ” 标示了这个生成器,也就是说这个生成器的名字是 PK_SEQ。这个 Table 属性标示了用哪个表来存贮生成的主键,在这个例子中,用“ SEQUENCE_TABLE” 来存储主键,数据库中有对应的 SEQUENCE_TABLE 表。其中 pkColumnName 属性用来指定的是生成器那个表中的主键,也就是 SEQUENCE_TABLE 这个表的主键的名字。属性 valueColumnName 指定列是用来存储最后生成的那个主键的值。

也可以使用持久化引擎提供的缺省得 Table,例如:

public class PK implements Serializable {    private static final long serialVersionUID = 1L;      @Id    @GeneratedValue(strategy = GenerationType.TABLE)       private Long id; // Getters and Setters }

 

hibernate主键策略生成器

  • native: 对于 oracle 采用 Sequence 方式,对于MySQL 和 SQL Server 采用identity(自增主键生成机制),native就是将主键的生成工作交由数据库完成,hibernate不管
  • 采用128位的uuid算法生成主键,uuid被编码为一个32位16进制数字的字符串。占用空间大(字符串类型)。
  • assigned: 在插入数据的时候主键由程序处理(即程序员手动指定),等同于JPA中的AUTO。
  • identity: 使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence(MySQL 和 SQL Server 中很常用)。 等同于JPA中的INDENTITY。
  • increment: 这个是由Hibernate在内存中生成主键,每次增量为1。可以跨数据库。插入数据的时候hibernate会给主键添加一个自增的主键,但是一个hibernate实例就维护一个计数器,所以在多个实例运行的时候不能使用这个方法。

increment策略:

@Id    @GeneratedValue(generator="increment")    @GenericGenerator(name="increment",strategy="increment")

native策略:

@Id    @GeneratedValue(generator = "NativeGenerator")    @GenericGenerator(name = "NativeGenerator", strategy = "native")

identity策略:

@Id    @GeneratedValue(generator = "IDGenerator")    @GenericGenerator(name = "IDGenerator", strategy = "identity")

等价于JPA中的IDENTITY策略

@Id@GeneratedValue(strategy=GenerationType.IDENTITY)

 

assigned策略:

@Id    @GeneratedValue(generator="paymentableGenerator")    @GenericGenerator(name="paymentableGenerator", strategy="assigned")

等价于JPA中的AUTO策略

@Id  @GeneratedValue(GenerationType.AUTO)

uuid策略:

@Id    @GeneratedValue(generator = "paymentableGenerator")    @GenericGenerator(name = "paymentableGenerator", strategy = "uuid")

 

转载地址:http://gfgai.baihongyu.com/

你可能感兴趣的文章
wsl2 Ubuntu 展示页面
查看>>
php 代码技巧
查看>>
mysql 源码缩写概念注释
查看>>
项目管理--持续更新
查看>>
代码质量
查看>>
钉钉发送图片
查看>>
shell脚本判断闰年的逻辑表达式
查看>>
数据对齐 posix_memalign 函数详解
查看>>
golang 将json串转换为树状结构
查看>>
java 日志配置
查看>>
elasticsearch 分片选择
查看>>
elasticsearch 之jvm配置
查看>>
elasticsearch update性能提升技巧
查看>>
yaml文件嵌套
查看>>
elasticsearch 命令调试
查看>>
index 特定情形的设置
查看>>
Linux hung参数
查看>>
elasticsearch 运维reroute 去除index丢失分片
查看>>
elasticsearch 创建index 原则
查看>>
elasticsearch index设置
查看>>