读书人

JPA学习札记-EJB-03JPA主键生成策略总

发布时间: 2012-08-24 10:00:21 作者: rapoo

JPA学习笔记-EJB-03JPA主键生成策略总结--1

总结一下关于JPA的主键生成策略,JPA是用@GeneratedValue标记来注释的。一般的我把主键生成分成两大类。第一个就是简单的单字段主键类型,一个就是复杂的复合主键类型。我们分2种情况分别讨论。

第一种单字段主键类型,看上去简单,无非就是一个id字段呗,实际上这个主键字段在JPA,还有任何的ORM框架中都是有很多种生成策略的。

一般是如下4种:

1.?????? AUTO:自动自增生成

2.?????? TABLE:自定义表生成器

3.?????? Identity:像MS SQL支持Identity字段的生成主键策略

4.?????? Sequence:像Oracle支持Sequence的生成主键策略

?

1:自动生成主键AUTO

?????? AUTO是默认的主键生成策略,使用了AUTO策略,JPA会根据不同的数据库类型来实现自增策略。比如MySql的表主键是自增1的,那么此策略就会按照数据库的自增1策略,每次插入数据库记录的时候都会自增1。Java代码片段如下:

??? @Id

??? @GeneratedValue(strategy=GenerationType.AUTO)

??? private Integer id;

2:自定义表生成器TABLE

?????? 自定义表生成器是在数据库中再建立一张新的表,这张表不是业务表,而是一张特殊表,这张表是专门用来管理整个数据库的主键的具体值的。在数据库中建立一张表如下图所示:
JPA学习札记-EJB-03JPA主键生成策略总结-1
?那么相应的Java片段如下所示:

??? @Id

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

??? @TableGenerator(

?????????? name = "myTablePK",

?????????? table = "tb_pk",

?????????? pkColumnName = "table_PK_name",

?????????? pkColumnValue = "tb_contact_pk",

?????????? valueColumnName = "table_PK_value",

?????????? allocationSize = 1)

??? private Integer id;

下面对@TableGenerator标记的属性说明一下:

Name:引用@GeneratedValue里面的generator的值

Table:数据库中专门用于生成主键的特殊表的表名

pkColumnName:tb_pk表中哪个字段代表了被服务(需要生成主键表)的表名

valueColumnName:指定此辅助表的哪个字段存储了主键的具体值

pkColumnValue:指明一个主键名称,依靠这个名称可以在这张特殊表中找到唯一的table_PK_value的值,而这个值就是具体的主键值。换句话说,数据库有几个业务表,这张表就应该有几条记录才对(除去复合主键的情况)

allocationSize:代表自增数

下面自己再写一个测试方法,这次注释掉主键set那一句,代码如下:

/**

??? ?* 保存ContactEO实体单元测试

??? ?*

??? ?* @throws NamingException

??? ?*/

??? public void test03() throws NamingException {

?

?????? // 建立实体

?????? ContactEO contactEO = new ContactEO();

??????

?????? //注释掉主键这句话

?????? //contactEO.setId(2);

?

?????? contactEO.setName("测试主键table策略");

?

??? ??? contactEO.setMessage("表策略");

?

?????? contactEO.setEmail("suhuanzheng77848@163.com");

?

?????? contactEO.setPrice(9999999911.12);

?

?????? // 对byte属性的赋值

?????? try {

?

?????????? // 读取本机一个文件

?????????? File file = new File("c://22.jpg");

?????????? if (file != null) {

????????????? FileInputStream fis = new FileInputStream(file);

????????????? if (fis != null) {

????????????????? int len = fis.available();

????????????????? byte[] xml = new byte[len];

????????????????? fis.read(xml);

?

????????????????? // 赋值

????????????????? contactEO.setPicture(xml);

????????????? }

?????????? }

?

?????? } catch (Exception e) {

?????????? e.printStackTrace();

?????? }

?

?????? // 获得应用服务上下文

?????? Context ctx = getInitialContext();

?

?????? Object object = ctx.lookup("ContactServiceImpl/remote");

?

?????? // 接口

?????? IContactService contactService = (IContactService) PortableRemoteObject

????????????? .narrow(object, IContactService.class);

?

?????? // 调用接口保存方法

?????? contactService.saveContact(contactEO);

?

??? }

执行后,数据库记录如下:

tb_contact记录
JPA学习札记-EJB-03JPA主键生成策略总结-1
?可以看到id=4的是tb_pk表辅助生成的值。

tb_pk表记录如下
JPA学习札记-EJB-03JPA主键生成策略总结-1
?可以看到,tb_pk这张表的table_PK_value的值改变了。

?

?

读书人网 >软件架构设计

热点推荐