技术开发 频道

实体标识的自动生成

数据库表

  除了使用容器生成的实体标识,或者借助于数据库的自增长字段或者序列号等方式生成实体标识之外,我们还可以选择借助数据库表来自动生成实体标识。原理是我们提供一个独立的数据库表,该表的主键列 ( 假设列名 ID) 记录实体编号的特征字符串 ( 假设存在一条记录的 ID 为 customID),另外一列 ( 假设列名为 SEQUENCE_VALUE) 记录该特征字符串对应实体标识的最大值。编写实体代码时,我们指定实体标识由数据库表中指定的特征字符串 ( 如 customID) 对应的列 SEQUENCE_VALUE 处理,当有新的实体被持久化时,容器将获取行 customID、列 SEQUENCE_VALUE 对应的数值 +1 后作为新实体的标识,同时将该列的值也自动 +1。

  要将实体标识的自动生成委托给数据库表,需要数据库和实体定义的双方配合才能够达到:首先,必须在数据库中创建合适的保存实体标识的表,另外还需要为实体标识字段提供 TableGenerator 注释,设置它的参数,为实体类提供关于数据库表、字段的信息,同时将实体类中实体标识字段的 GeneratedValue 注释的 stragety 属性的值设置为 GenerationType.Table,将 generator 属性的值设置为 SequenceGenerator 注释的 name 属性的值。

  我们以 Animal 实体类来说明使用数据库表自动生成实体标识所需要采取的步骤:我们假设存在这样的场景,Animal 实体的标识由应用程序中自定义的数据库表 MY_KEYS 自动生成,MY_KEYS 表中有两列,一列是 KEYID,它保存实体标识的特征值,一列是 KEYVALUE,它保存实体当前的最大编号,除此之外,我们还决定使用 ANIMALID 作为 Animal 实体标识的特征字符串。

  首先,在数据库中使用下面的 SQL 语句创建名为 MY_KEYS 的数据库表。在 OpenJPA 容器中,如果我们没有创建 MY_KEYS 表,OpenJPA 容器将帮我们自动生成对应的表结构。

  清单 9. 创建数据库表 MY_KEYS

CREATE TABLE MY_KEYS (
    KEYID
VARCHAR(255) NOT NULL,
    KEYVALUE
BIGINT,
    
PRIMARY KEY (KEYID)
)

  在数据库部分创建合适的数据库表后,在实体 Animal 的定义中,我们需要将 id 字段 GeneratedValue 注释的 stragety 属性的值设置为 GenerationType.TABLE,设置它的 generator 属性的值为 TableGenerator。我们还需要为 id 字段提供另外一个注释 TableGenerator,设置它的 name 属性为 TableGenerator,设置它的 table 属性为 MYKEYS、pkColumnName 属性为 KEYID、valueColumnName 属性为 KEYVALUE、 ANIMALID 属性为 ANIMALID。Animal 实体类修改后的代码片段如下。

  清单 10. 标识由数据库表生成的 Animal 实体类

1.    import javax.persistence.Entity;
2.    import javax.persistence.GeneratedValue;
3.    import javax.persistence.GenerationType;
4.    import javax.persistence.Id;
5.    
6.    @Entity
7.    public class Animal {
8.        @Id
9.        @GeneratedValue(strategy = GenerationType.TABLE, generator = " TableGenerator ")
10.        @TableGenerator(name = " TableGenerator", table = "MY_KEYS",
                pkColumnName
= "KEYID", valueColumnName = "KEYVALUE", pkColumnValue = "ANIMALID")
11.        private long id;
12.        private String name;
13.      
14.      …
15.    
16.    }

  调用代码

  上面的章节中我们学习了分别使用四种方式来自动生成实体的标识,由于这四种情况下,Animal 实体的标识都由 OpenJPA 和数据库协作后自动生成,对于开发者而言,这个过程是透明的,因此我们可以使用相同的方式来创建这些实体:创建新的 Animal 实例的时候不再需要为主键字段提供属性值,只需要设置 Animal 实例的非标识字段 name 的值即可。下面的代码演示了 Animal 实例的持久化代码,请注意代码中并没有调用 Animal 实例的 setId 方法。

  清单 11. Animal 实例的持久化代码

1.    EntityManagerFactory factory = Persistence.
2.             createEntityManagerFactory(
3.             "jpa-unit", System.getProperties());
4.        EntityManager em = factory.createEntityManager();
5.        em.getTransaction().begin();
6.    
7.        Animal animal = new Animal();
8.        // 此处不需要调用 animal 的 setId 方法
9.        animal.setName("ba guai!");
10.    em.persist(animal);
11.    
12.    em.getTransaction().commit();
13.    em.close();
14.    em2.close();
15.    factory.close();

  总结

  本文介绍了开发者使用 OpenJPA 实现实体标识自动生成时可选择使用的注释,并且结合简单的例子,分别介绍了OpenJPA 中实现容器管理的实体标识自动生成、结合数据库自增长字段、序列号、数据库表等特性实现实体标识自动生成时注释的具体用法和操作步骤。

0
相关文章