技术开发 频道

开发第一个 Open JPA 应用

  编译实体类

 

  打开命令行控制台,进入 C:\OpenJPAExamples 目录,执行下面的系列语句可以编译实体类 Animal.java。

1 C:\OpenJPAExamples>set OPENJPA_HOME=C:\OpenJPA
2 C:\OpenJPAExamples>set classpath=%OPENJPA_HOME%\lib\persistence-api-1.0.jar
3 C:\OpenJPAExamples>javac Animal.java -d
4

  [注] 上面的命令行中第一行出现的 C:\OpenJPA 是指 OpenJPA 框架的安装目录。如果您没有使用 C:/OpenJPA 作为 OpenJPA 的安装目录,请将 OPENNJPA_HOME 的值修改为您安装 OpenJPA 的目录。

  增强(Enhance)实体类

  Enhance 是使用 OpenJPA 必须的一个步骤,所谓 Enhance 是指使用 OpenJPA 提供的工具 PCEnhancer(org.apache.openjpa.enhance.PCEnhancer)对实体类进行处理的过程,被 Enhance 过的实体类能够支持性能优化、懒惰式装载等高级特性。

  OpenJPA 支持在编译时、部署时、运行时增强实体类,我们以编译时为例了解如何增强实体类。我们使用下面的系列语句完成实体类的增强(Enhance)。

1.    C:\OpenJPAExamples>set OPENJPA_HOME=C:\OpenJPA
2.    C:\OpenJPAExamples>set classpath= %OPENJPA_HOME%\lib\commons-collections-3.2.jar;
    
%OPENJPA_HOME%\lib\commons-lang-2.1.jar;
    
%OPENJPA_HOME%\lib\commons-logging-1.0.4.jar;
    
%OPENJPA_HOME%\lib\commons-pool-1.3.jar;
    
%OPENJPA_HOME%\lib\geronimo-j2ee-connector_1.5_spec-1.0.1.jar;
    
%OPENJPA_HOME%\lib\geronimo-jms_1.1_spec-1.0.1.jar;
    
%OPENJPA_HOME%\lib\geronimo-jta_1.0.1B_spec-1.0.1.jar;
    
%OPENJPA_HOME%\lib\persistence-api-1.0.jar;
    
%OPENJPA_HOME%\lib\serp-1.11.0.jar;
    
%OPENJPA_HOME%\openjpa-all-0.9.6-incubating.jar
3.    C:\OpenJPAExamples>java org.apache.openjpa.enhance.PCEnhancer Animal.java

  有兴趣的读者可以使用反射(Reflect)机制获取经过 Enhance 的类的信息,清单 3 中给出了被 Enhance 过后 Animal 实体类的类声明和方法签名信息,从中我们可以看到 Animal 被增加了新的 org.apache.openjpa.enhance.PersistenceCapable 接口,而该接口声明的方法都是和实体创建、状态保持等相关的。事实上,OpenJPA 通过 Enhance 过程修改我们的实体类,扩充了实体类的能力,从而实现性能优化、懒惰式装载等高级特性。

  清单 3 Animal 被 Enhance 过后的类声明和方法信息

1.    public class org.vivianj.openjpa.entity.Animal
2.        extends java.lang.Object
3.        implements org.apache.openjpa.enhance.PersistenceCapable{
4.        protected transient org.apache.openjpa.enhance.StateManager pcStateManager;
5.        protected transient byte pcFlags;
6.        static java.lang.Class class$Ljava$lang$String;
7.        static java.lang.Class class$Lorg$vivianj$openjpa$entity$Animal;
8.        public org.vivianj.openjpa.entity.Animal();
9.        public int getId();
10.        public void setId(int);
11.        public java.lang.String getName();
12.        public void setName(java.lang.String);
13.        static final {};
14.        static java.lang.Class class$(java.lang.String);
15.        protected void pcClearFields();
16.        public org.apache.openjpa.enhance.PersistenceCapable pcNewInstance(
17.        org.apache.openjpa.enhance.StateManager, java.lang.Object, boolean);
18.        public org.apache.openjpa.enhance.PersistenceCapable pcNewInstance(
19.        org.apache.openjpa.enhance.StateManager, boolean);
20.        protected static int pcGetManagedFieldCount();
21.        public void pcReplaceField(int);
22.        public void pcReplaceFields(int[]);
23.        public void pcProvideField(int);
24.        public void pcProvideFields(int[]);
25.        protected void pcCopyField(org.vivianj.openjpa.entity.Animal, int);
26.        public void pcCopyFields(java.lang.Object, int[]);
27.        public java.lang.Object pcGetGenericContext();
28.        public java.lang.Object pcFetchObjectId();
29.        public boolean pcIsDeleted();
30.        public boolean pcIsDirty();
31.        public boolean pcIsNew();
32.        public boolean pcIsPersistent();
33.        public boolean pcIsTransactional();
34.        public boolean pcSerializing();
35.        public void pcDirty(java.lang.String);
36.        public org.apache.openjpa.enhance.StateManager pcGetStateManager();
37.        public java.lang.Object pcGetVersion();
38.        public void pcReplaceFlags();
39.        public synchronized void pcReplaceStateManager(
40.              org.apache.openjpa.enhance.StateManager)      
41.                  throws java.lang.SecurityException;
42.        public void pcCopyKeyFieldsToObjectId(
43.            org.apache.openjpa.enhance.FieldSupplier, java.lang.Object);
44.        public void pcCopyKeyFieldsToObjectId(java.lang.Object);
45.        public void pcCopyKeyFieldsFromObjectId(
46.             org.apache.openjpa.enhance.FieldConsumer, java.lang.Object);
47.        public void pcCopyKeyFieldsFromObjectId(java.lang.Object);
48.        public java.lang.Object pcNewObjectIdInstance(java.lang.Object);
49.        public java.lang.Object pcNewObjectIdInstance();
50.        public java.lang.Boolean pcIsDetached();
51.        public java.lang.Object pcGetDetachedState();
52.        public void pcSetDetachedState(java.lang.Object);
53.    }

  将新创建的实体类注册到 OpenJPA 容器中

  在 OpenJPA 框架中,如果创建了新的实体类,必须通过修改配置文件,将它注册到 OpenJPA 容器中,该实体类才能够被 OpenJPA 管理。将实体类方法注册到 OpenJPA 容器中的方法是在 persistence.xml 中对应的 persistence-unit 元素下增加子元素 class,元素的内容就是被注册持久类的全名。比如我们要把 org.vivianj.openjpa.entity.Animal 注册到 OpenJPA 容器中,我们可以在 persistence.xml 中加入如下内容:

1.    <persistence >
2.        
<persistence-unit >
3.            …
4.            
<class>org.vivianj.openjpa.entity.Animal</class>
5.            …
6.        
</persistence-unit>
7.    
</persistence>

  准备数据库

  在 MySQL 数据库中新建名为“openjpa”的数据库。新创建数据库的访问用户为“openjpa”,密码设置为“openjpa”,新创建的用户“openjpa”必须具有访问读写“openjpa”数据库数据的权限。

  保持实体类和数据库表结构一致性

  OpenJPA 中提供了专门的 MappingTool(org.apache.openjpa.jdbc.meta.MappingTool)工具协助开发者保持实体类和数据库表结构之间的一致性。MappingTool 工具能够自动的根据实体类中提供的注释(Annotation),识别出对象、对象之间的继承/包含等关系以及如何在关系型数据库中处理这些关系的设置,自动保证实体类和数据库之间的一致性,开发者也可以选择使用 OpenJPA 生成创建数据库所需要的 SQL 语句,然后手动的保持实体类和数据库之间的一致性。

  可以使用下面的命令语句直接通过 MappingTool 在数据库中创建 OpenJPA 应用所需要的数据库表。

1 java org.apache.openjpa.jdbc.meta.MappingTool Animal.java

  命令执行完成后,我们通过 MySQL 的客户端访问 OpenJPA 数据库,可以发现里面已经创建了名为“animal”的数据表。如果开发者不想让 MappingTool 自动维护 OpenJPA 和数据库之间的映射,而只是想让 MappingTool 协助生成创建数据库所需要的数据库表定义文件(DDL),可以使用下面的命令语句,其中的参数 -sql 的值就是生成数据库表定义文件的位置。

  比如要将生成的数据库表定义文件写入当前文件夹下 animal.sql 文件的命令如下:

1 java org.apache.openjpa.jdbc.meta.MappingTool –sql animal.sql Animal.java

  [注] 要成功执行 MapptingTool 工具,必须先将数据库的 JDBC 驱动放入到 classpath 中,否则会得到一个 org.apache.openjpa.util.StoreException 类型的异常信息。

  访问持久化对象

  访问 OpenJPA 容器中管理的持久化对象所需要的基本步骤如下:

  获取 OpenJPA 容器中配置好的 EntityManagerFactory 对象;

  从 EntityManagerFactory 中获取 EntityManager 对象;

  如果是处理持久化对象的创建、更新、删除动作,还需要从 EntityManager 中获取 EntityTransaction,并且调用其 begin(commit)方法显式的启动(提交)事务;

  操作持久化对象

  调用 EntityManager 的 persist 方法可以持久化对象到数据库中;

  调用 EntityManager 的 merge 方法可以更新对象状态;

  调用 EntityManager 的 remove 方法可以删除持久化对象,另外一种选择是通过 Query 接口删除对象。

  查询持久化对象

  根据对象的主键查找符合条件的对象,可以直接使用 EntityManager 的 find 方法;

  要查询 EntityManager 中符合条件的对象列表,还需要借助 Query 接口和 JPQL(Java Persistence Query Language)查询语言。

0
相关文章