JPA主键生成策略

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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值