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策略,每次插入数据库记录的时候都会自增1Java代码片段如下:

    @Id

    @GeneratedValue(strategy=GenerationType.AUTO)

    private Integer id;

2:自定义表生成器TABLE

       自定义表生成器是在数据库中再建立一张新的表,这张表不是业务表,而是一张特殊表,这张表是专门用来管理整个数据库的主键的具体值的。在数据库中建立一张表如下图所示:
JPA学习笔记-EJB-03JPA主键生成策略总结--1_第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:数据库中专门用于生成主键的特殊表的表名

pkColumnNametb_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("[email protected]");

 

       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_第2张图片
 可以看到id=4的是tb_pk表辅助生成的值。

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

 

 

你可能感兴趣的:(oracle,mysql,jpa,ejb,单元测试)