hibernate中的@GeneratedValue与@GenericGenerator

栏目: Hibernate · 发布时间: 3年前

来源: blog.csdn.net

内容简介:hibernate中的@GeneratedValue与@GenericGenerator

本文转载自:http://blog.csdn.net/u011781521/article/details/72210980?utm_source=tuicool&utm_medium=referral,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有。

1、GeneratedValue与GenericGenerator的区别

@GeneratorValue注解----JPA通用策略生成器

@GenericGenerator注解----自定义主键生成策略

一个是通用的一个是自定义的这就是他们的区别。

2、@GeneratorValue注解----JPA通用策略生成器

GeneratorValue 属于一个JPA接口,其接口下包含了两个抽象的参数,GenerationType类型的strategy和String类型的generator,并且两个参数都有相应的默认值。

@Target({METHOD,FIELD})    

    @Retention(RUNTIME)    

    public @interface GeneratedValue{    

        GenerationType strategy() default AUTO;    
        String generator() default "";    

    }

1.generator  : String  //JPA 持续性提供程序为它选择的主键生成器分配一个名称,如果该名称难于处理、是一个保留字、与事先存在的数据模型不兼容或作为 数据库 中的主键生成器名称无效,则将 generator 设置为要使用的 String 生成器名称。
例如用hibernate的uuid主键生成器就如下来写:

@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid.hex")

2.strategy    : String  // 指定生成策略

其中GenerationType: 

public enum GenerationType{    

    TABLE,    

    SEQUENCE,    

    IDENTITY,    

    AUTO   

}

可以看出JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO. 


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

1、TABLE

使用一个特定的数据库表格来保存主键,持久化引擎通过关系数据库的一张特定的表格来生成主键,这种策略的好处就是不依赖于外部环境和数据库的具体实现,在不同数据库间可以很容易的进行移植,但由于其不能充分利用数据库的特性,所以不会优先使用。该策略一般与另外一个注解一起使用@TableGenerator,@TableGenerator注解指定了生成主键的表(可以在实体类上指定也可以在主键字段或属性上指定),然后JPA将会根据注解内容自动生成一张表作为序列表(或使用现有的序列表)。如果不指定序列表,则会生成一张默认的序列表,表中的列名也是自动生成,数据库上会生成一张名为sequence的表(SEQ_NAME,SEQ_COUNT)。序列表一般只包含两个字段:第一个字段是该生成策略的名称,第二个字段是该关系表的最大序号,它会随着数据的插入逐渐累加。

示例:

User实体类:

package com.fendo.Entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.TableGenerator;


@Entity
@Table(name="USER_TABLE")
public class UserEntity {
	
	
	private Integer uid;
	private String uname;
	private String uage;
	private String usex;
	private String usom;
	
	@Id
	@Column(name="id")
	@GeneratedValue(strategy=GenerationType.TABLE,generator="table_gen")
	@TableGenerator(
			name = "table_gen",  
		    table="fendo_generator",  
		    pkColumnName="seq_name",     //指定主键的名字
		    pkColumnValue="fendos",      //指定下次插入主键时使用默认的值
		    valueColumnName="seq_id",    //该主键当前所生成的值,它的值将会随着每次创建累加
		    initialValue = 1,            //初始化值
		    allocationSize=1             //累加值
		    )
	public Integer getUid() {
		return uid;
	}
	public void setUid(Integer uid) {
		this.uid = uid;
	}
	
	@Column(name="uname")
	public String getUname() {
		return uname;
	}
	public void setUname(String uname) {
		this.uname = uname;
	}
	
	@Column(name="uage")
	public String getUage() {
		return uage;
	}
	public void setUage(String uage) {
		this.uage = uage;
	}
	
	@Column(name="usex")
	public String getUsex() {
		return usex;
	}
	public void setUsex(String usex) {
		this.usex = usex;
	}
	
	@Column(name="usom")
	public String getUsom() {
		return usom;
	}
	public void setUsom(String usom) {
		this.usom = usom;
	}
}

表字段:

hibernate中的@GeneratedValue与@GenericGenerator

对应的SQL文件:

CREATE TABLE `user_table` (
  `id` int(11) NOT NULL,
  `uage` varchar(255) DEFAULT NULL,
  `uname` varchar(255) DEFAULT NULL,
  `usex` varchar(255) DEFAULT NULL,
  `usom` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

然后创建序列表:

hibernate中的@GeneratedValue与@GenericGenerator

并插入一条数据

INSERT INTO `fendo_generator` VALUES ('1', 'fendo');

对应的SQL文件为:

CREATE TABLE `fendo_generator` (
  `seq_id` int(11) NOT NULL,
  `seq_name` varchar(255) NOT NULL,
  PRIMARY KEY (`seq_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

和以下的代码相对应:

@GeneratedValue(strategy=GenerationType.TABLE,generator="table_gen")
@TableGenerator(
    name = "table_gen",          //name对应@GeneratedValue中generator 引用的名字
    table="fendo_generator",       //对应数据库表中的名字,表键-字段名
    pkColumnName="seq_name",       //指定主键的名字
    pkColumnValue="fendos",       //指定下次插入主键时使用默认的值,表键-字段值
    valueColumnName="seq_id",      //该主键当前所生成的值,它的值将会随着每次创建累加,表值-字段名
    initialValue = 1,           //初始化值
    allocationSize=1            //累加值,每次累加1
)

@TableGenerator的定义为:

@Target({TYPE, METHOD, FIELD})   

@Retention(RUNTIME)  

public @interface TableGenerator {  

  String name();  

  String table() default "";  

  String catalog() default "";  

  String schema() default "";  

  String pkColumnName() default "";  

  String valueColumnName() default "";  

  String pkColumnValue() default "";  

  int initialValue() default 0;  

  int allocationSize() default 50;  

  UniqueConstraint[] uniqueConstraints() default {};  

}

属性说明: 


name属性表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中。 


table属性表示表生成策略所持久化的表名,例如,这里表使用的是数据库中的“fendo_generator”。


catalog属性和schema具体指定表所在的目录名或是数据库名。 


pkColumnName属性的值表示在持久化表中,该主键生成策略所对应键值的名称。例如在“ fendo_generator ”中将“seq_name”作为主键对应值得名称,也就是这个主键所对应的名字。如上 seq_name ”为"fendo",那么它所对应的值为"1"


valueColumnName属性的值表示在持久化表中,该主键当前所生成的值,它的值将会随着每次创建累加。例如,在“ fendo_generator ”中将“seq_id”作为主键的值 


pkColumnValue属性的值表示在持久化表中,该生成策略生成主键所对应的名字。例如在“ fendo_generator ”表中,将“ seq_name ”的值为“fendos”。


initialValue表示主键初识值,默认为0。 


allocationSize表示每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50。 


UniqueConstraint与@Table标记中的用法类似。 

测试类:

public class App 
{
    public static void main( String[] args )
    {
    	SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();  
    	Session session = sessionFactory.getCurrentSession();  
    	Transaction tx = session.beginTransaction();  
        

    	UserEntity ue=new UserEntity();
    	ue.setUage("19");
    	ue.setUname("fendo");
    	ue.setUsex("男");
    	ue.setUsom("123456");
    	
        session.save(ue);  
    	
        tx.commit();
        session.close();
    }
    
   
}

第一次执行时所执行的SQL语句如下:

Hibernate: 
    select
        tbl.seq_id 
    from
        fendo_generator tbl 
    where
        tbl.seq_name=? for update
            
Hibernate: 
    insert 
    into
        fendo_generator
        (seq_name, seq_id)  
    values
        (?,?)
Hibernate: 
    update
        fendo_generator 
    set
        seq_id=?  
    where
        seq_id=? 
        and seq_name=?
Hibernate: 
    insert 
    into
        USER_TABLE
        (uage, uname, usex, usom, id) 
    values
        (?, ?, ?, ?, ?)

此时fendo_generator表就会发生变化会:

hibernate中的@GeneratedValue与@GenericGenerator

user_table会多出一条数据:

hibernate中的@GeneratedValue与@GenericGenerator

再执行一次表中的结果就会变成如下:

hibernate中的@GeneratedValue与@GenericGenerator

hibernate中的@GeneratedValue与@GenericGenerator

完整示例: http://download.csdn.net/detail/u011781521/9843151


2、SEQUENCE 

在某些数据库中,不支持主键自增长,比如Oracle,其提供了一种叫做"序列(sequence)"的机制生成主键。此时,GenerationType.SEQUENCE就可以作为主键生成策略。该策略的不足之处正好与TABLE相反,由于只有部分数据库(Oracle,PostgreSQL,DB2)支持序列对象,MYsql不支持序列,所以该策略一般不应用于其他数据库。类似的,该策略一般与另外一个注解一起使用@SequenceGenerator,@SequenceGenerator注解指定了生成主键的序列.然后JPA会根据注解内容创建一个序列(或使用一个现有的序列)。如果不指定序列,则会自动生成一个序列SEQ_GEN_SEQUENCE。

@Id  
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="fendo_seq")  
@SequenceGenerator(name="fendo_seq", sequenceName="seq_name")

@SequenceGenerator定义:

@Target({TYPE, METHOD, FIELD})   

@Retention(RUNTIME)  

public @interface SequenceGenerator {  

 String name();  

 String sequenceName() default "";  

 int initialValue() default 0;  

 int allocationSize() default 50;  

}

属性说明:

name属性: 表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中。

sequenceName属性 表示生成策略用到的数据库序列名称。 

initialValue属性 表示主键初识值,默认为0。 

allocationSize属性 表示每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50。


3、IDENTITY 

此种主键生成策略就是通常所说的主键自增长,数据库在插入数据时,会自动给主键赋值,比如 MySQL 可以在创建表时声明"auto_increment" 来指定主键自增长。该策略在大部分数据库中都提供了支持(指定方法或关键字可能不同),但还是有少数数据库不支持,所以可移植性略差。使用自增长主键生成策略是只需要声明strategy = GenerationType.IDENTITY即可。

@Id  
@GeneratedValue(strategy = GenerationType.IDENTITY)

需要注意的是,同一张表中自增列最多只能有一列。

4、AUTO

把主键生成策略交给持久化引擎(persistence engine),持久化引擎会根据数据库在以上三种主键生成策略中选择其中一种。此种主键生成策略比较常用,由于JPA默认的生成策略就是GenerationType.AUTO,所以使用此种策略时.可以显式的指定@GeneratedValue(strategy = GenerationType.AUTO)也可以直接@GeneratedValue。

@Id  
@GeneratedValue(strategy = GenerationType.AUTO)

在指定主键时,如果不指定主键生成策略,默认为AUTO。

@Id

跟下面的定义是一样的。   

@Id  
@GeneratedValue(strategy = GenerationType.AUTO)

3、 @GenericGenerator 注解 ----自定义主键生成策略

GenericGenerator一般配合 GeneratorValue来用比如说


Java代码  

@Id  
@GeneratedValue(GenerationType.AUTO)

可以用hibernate特有以下用法来实现 


Java代码  

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

@GenericGenerator的定义: 

@Target({PACKAGE, TYPE, METHOD, FIELD})  

@Retention(RUNTIME)  

public @interface GenericGenerator {  

 /** 

  * unique generator name 

  */  

 String name();  

 /** 

  * Generator strategy either a predefined Hibernate 

  * strategy or a fully qualified class name. 

  */  

 String strategy();  

 /** 

  * Optional generator parameters 

  */  

 Parameter[] parameters() default {};  

}

name属性指定生成器名称。 

strategy属性指定具体生成器的类名。 

有以下参数可选:

static {  

  GENERATORS.put("uuid", UUIDHexGenerator.class);  

  GENERATORS.put("hilo", TableHiLoGenerator.class);  

  GENERATORS.put("assigned", Assigned.class);  

  GENERATORS.put("identity", IdentityGenerator.class);  

  GENERATORS.put("select", SelectGenerator.class);  

  GENERATORS.put("sequence", SequenceGenerator.class);  

  GENERATORS.put("seqhilo", SequenceHiLoGenerator.class);  

  GENERATORS.put("increment", IncrementGenerator.class);  

  GENERATORS.put("foreign", ForeignGenerator.class);  

  GENERATORS.put("guid", GUIDGenerator.class);  

  GENERATORS.put("uuid.hex", UUIDHexGenerator.class); //uuid.hex is deprecated  

  GENERATORS.put("sequence-identity", SequenceIdentityGenerator.class);  

}


1、native

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


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

3、hilo

@GeneratedValue(generator = "fendo_Generator")    
@GenericGenerator(name = "fendo_Generator", strategy = "hilo")

4、assigned 

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

5、identity

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

6、select 

@GeneratedValue(generator = "fendo_Generator")  
@GenericGenerator(name="fendo_Generator", strategy="select",  
     parameters = { @Parameter(name = "key", value = "idstoerung") })

7、sequence

@GeneratedValue(generator = "fendo_Generator")  
@GenericGenerator(name = "fendo_Generator", strategy = "sequence",   
         parameters = { @Parameter(name = "sequence", value = "seq_sum") })

8、seqhilo

@GeneratedValue(generator = "fendo_Generator")  
@GenericGenerator(name = "fendo_Generator", strategy = "seqhilo",   
         parameters = { @Parameter(name = "max_lo", value = "5") })

9、increment

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

10、foreign

@GeneratedValue(generator = "fendo_Generator")  
@GenericGenerator(name = "fendo_Generator", strategy = "foreign",   
         parameters = { @Parameter(name = "property", value = "employee") })

注意:直接使用@PrimaryKeyJoinColumn

@OneToOne(cascade = CascadeType.ALL)   
@PrimaryKeyJoinColumn

例如

@Entity  
public class Employee {  
  @Id 
  Integer id;  
      
  @OneToOne 
  @PrimaryKeyJoinColumn  
  EmployeeInfo info;  
  ...  
} 

应该为

@Entity  
public class Employee {  
  @Id   
  @GeneratedValue(generator = "fendo_Generator")  
  @GenericGenerator(name = "fendo_Generator", strategy = "foreign",   
         parameters = { @Parameter(name = "property", value = "info") })   
  Integer id;  
      
  @OneToOne  
  EmployeeInfo info;  
  ...  
}

11、guid

@GeneratedValue(generator = "fendo_Generator")    
@GenericGenerator(name = "fendo_Generator", strategy = "guid")

12、uuid.hex

@GeneratedValue(generator = "fendo_Generator")    
@GenericGenerator(name = "fendo_Generator", strategy = "uuid.hex")

13、sequence-identity

@GeneratedValue(generator = "fendo_Generator")  
@GenericGenerator(name = "fendo_Generator", strategy = "sequence-identity",   
         parameters = { @Parameter(name = "sequence", value = "seq_sum") })

5、四种数据库的支持情况如下

数据库名称 支持的id策略
MySQL

GenerationType.TABLE

GenerationType.AUTO

GenerationType.IDENTITY

不支持GenerationType.SEQUENCE

Oracle

strategy=GenerationType.AUTO

GenerationType.SEQUENCE

GenerationType.TABLE

不支持GenerationType.IDENTITY

postgreSQL

GenerationType.TABLE

GenerationType.AUTO

GenerationType.IDENTITY

GenerationType.SEQUENCE

都支持

kingbase

GenerationType.TABLE

GenerationType.SEQUENCE

GenerationType.IDENTITY

GenerationType.AUTO

都支持


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

关注码农网公众号

关注我们,获取更多IT资讯^_^


为你推荐:

相关软件推荐:

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Hibernate

Hibernate

James Elliott / O'Reilly Media, Inc. / 2004-05-10 / USD 24.95

Do you enjoy writing software, except for the database code? Hibernate:A Developer's Notebook is for you. Database experts may enjoy fiddling with SQL, but you don't have to--the rest of the appl......一起来看看 《Hibernate》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具