我的java天地

jpa中用table来生成主键

将当前主键的值单独保存到一个数据库的表中,主键的值每次都是从指定的表中查询来获得,这种生成主键的方式也是很常用的。这种方法生成主键的策略可以适用于任何的数据库,不必担心不同数据库不兼容造成的问题。

使用以下SQL脚本创建一个表“tb_generator”,并插入两条数据,SQL脚本如下所示。

CREATE TABLE  tb_generator (

  id int(20) unsigned NOT NULL auto_increment,

  gen_name varchar(255) NOT NULL,

  gen_value int(20) NOT NULL,

  PRIMARY KEY  (id)

)

 

INSERT INTO tb_generator ( gen_name ,gen_value ) VALUES ( 'CUSTOMER_PK',1);

INSERT INTO tb_generator ( gen_name ,gen_value ) VALUES ( 'CONTACT_PK',100);

执行SQL语句后,表中的数据如图5.1所示。


图5.1  自动生成主键表tb_generator

现在有另外两个表customer和contact,它们每次新建记录时生成主键的值分别“CUSTOMER_PK”所对应的value值加1,“CONTACT_PK”所对应的value值加1。

下面就来具体看一下如何来配置主键的生成策略,以配置“customer”表为例,步骤如下。

(1)在Entity标记主键的位置,指定主键生成策略为“GenerationType.TABLE”,具体设置如下。

@Entity

@Table(name = "customer")

public final class CustomerEO implements java.io.Serializable {

 

         private Integer id;

 

         @Id

         @GeneratedValue(strategy = GenerationType.TABLE)

         public Integer getId() {

                   return this.id;

         }

 

         public void setId(Integer id) {

                   this.id = id;

         }

}

(2)指定生成主键策略的名称,例如这里命名为“customer_gen”。

         @Id

         @GeneratedValue(strategy = GenerationType.TABLE,generator="customer_gen")

         public Integer getId() {

                   return this.id;

         }

(3)使用@ TableGenerator标记定义表生成策略的具体设置,代码如下所示。

         @Id

         @GeneratedValue(strategy = GenerationType.TABLE,generator="customer_gen")

         @TableGenerator(name = "customer_gen",

                            table="tb_generator",

                            pkColumnName="gen_name",

                            valueColumnName="gen_value",

                            pkColumnValue="CUSTOMER_PK",

                            allocationSize=1

         )

         public Integer getId() {

                   return this.id;

         }

这样,当通过以下代码创建新的实体后,表tb_generator中“CUSTOMER_PK”的value的值将自动加1,如图5.2所示。

             CustomerEO customer = new CustomerEO();

             customer.setName("Janet");

             customer.setShortName("Jane");

             entityManager.persist(customer);


图5.2  添加新数据后表tb_generator

(4)@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 {};

}

在使用此@ TableGenerator标记时,需要注意以下几个问题。

l         该标记可以在类名、方法名、和属性名前。并且一旦在实体中标记,它不仅可以在本实体中使用,在其他的实体中也可以引用。它的作用范围是整个persist unit配置的实体类中。

例如以上的定义也可以写成:

@Entity

@Table(name = "customer")

@TableGenerator(name = "customer_gen",

                   table="tb_generator",

                   pkColumnName="gen_name",

                   valueColumnName="gen_value",

                   pkColumnValue="CUSTOMER_PK",

                   allocationSize=1

)

public class CustomerEO implements java.io.Serializable {

         ……

}

或者将其标注在ContactEO中,也是可以的。但建议标注在所作用的实体中,这样有助于方便查看。

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

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

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

l         pkColumnName属性的值表示在持久化表中,该主键生成策略所对应键值的名称。例如在“tb_generator”中将“gen_name”作为主键的键值

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

l         pkColumnValue属性的值表示在持久化表中,该生成策略所对应的主键。例如在“tb_generator”表中,将“gen_name”的值为“CUSTOMER_PK”。

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

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

l         UniqueConstraint与@Table标记中的用法类似,请读者参阅5.2.1小节。

用一个简单示意图表示持久化主键表和表生成策略,如图所示。

 

二.EJB3.0里的实体bean主键产生类型有一种是 GenerationType.TABLE,数据表如下:

 

 

 

 

 

 

 

里面有的一条示例数据:

gen_key gen_value
VENDOR_PART_ID 5

 

 

部分代码如下:

Java代码 复制代码
  1. @SuppressWarnings ( "serial" )   
  2. @Entity   
  3. @Table (name= "vendorpart" )   
  4. public   class  VendorPart  implements  Serializable {   
  5.   
  6.      private  Long vendorpartNumber;   
  7.      private  String myDescription;   
  8.      private   double  price;   
  9.        
  10.      private  Vendor vendor;   
  11.      private  Part part;   
  12.   
  13.      @TableGenerator (   
  14.             name= "vendorPartGen" // 命名表产生器   
  15.             table= "sequencegenerator" // 表产生器产生主键的表   
  16.             pkColumnName= "gen_key" // 主键表中主键列名   
  17.             pkColumnValue= "VENDOR_PART_ID" // 主键表中某个主键列   
  18.             allocationSize= 10 ,   
  19.             valueColumnName= "gen_value"   // 主键表中主键值的列名   
  20.     )   
  21.      @Id   
  22.      @Column (name= "vendorpartnumber" )   
  23.      @GeneratedValue (strategy=GenerationType.TABLE,generator= "vendorPartGen" )     // 产生器名字   
  24.      public  Long getVendorpartNumber() {   
  25.          return  vendorpartNumber;   
  26.     }   
  27.   
  28.      public   void  setVendorpartNumber(Long vendorpartNumber) {   
  29.          this .vendorpartNumber = vendorpartNumber;   
  30.     }   
  31.   
  32. // 。。。。   
  33.   
  34. }  


 

posted on 2009-06-25 17:59 tobyxiong 阅读(1188) 评论(0)  编辑  收藏 所属分类: java


只有注册用户登录后才能发表评论。


网站导航:
 
<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿(3)

随笔分类(144)

随笔档案(157)

相册

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜