[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[转帖]JPA 表生成器 GenerationType.TABLE

上一篇:[备忘]eclipse修改新建jsp文件的默认编码
下一篇:[转载]《iText in Action 2nd》读书笔记,中文文档

添加日期:2013/2/7 15:13:17 快速返回   返回列表 阅读4550次
将当前主键的值单独保存到一个数据库的表中,主键的值每次都是从指定的表中查询来获得,这种生成主键的方式也是很常用的。这种方法生成主键的策略可以适用于任何的数据库,不必担心不同数据库不兼容造成的问题。

使用以下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小节。
用一个简单示意图表示持久化主键表和表生成策略,如图所示。
 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved