下面的章节中我们将逐一了解如何通过OpenJPA 中的相关接口完成这些步骤。
获取 OpenJPA 容器中的 EntityManagerFactory
EntityManagerFactory 是 OpenJPA 中创建 EntityManager 的工厂,要想得到 EntityManager,就必须获取的相应的EntityManagerFactory。
EntityManagerFactory 通过 Persistence 的静态方法 createEntityManagerFactory 获得,该方法是一个重载的方法,支持不同的输入参数。最常用的是使用一个字符串作为参数,该字符串的内容是 EntityManagerFactory 的标识名,该标识名需要和 persistence.xml 文件中的 persistence-unit 元素的 name 属性保持一致。可以使用 null 作为 createEntityManagerFactory 方法的参数,这时候将使用 persistence.xml 中没有提供 name 属性的 persistence-unit 元素提供的参数来配置 EntityManagerFactory。
下面的代码段可以从 OpenJPA 容器中获取名为“mysql”的 EntityManagerFactory。
而它对应的 persistence.xml 文件中,应该有相应的 name 属性为“mysql”的 persistence-unit 元素,下面的配置是一个示例。
2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3. version="1.0">
4. <persistence-unit name="mysql" transaction-type="RESOURCE_LOCAL">
5. …
6. </persistence-unit>
7. </persistence>
为了提升软件的执行效率,我们通常选择在某一个范围内缓存 EntityManagerFactory 对象。在 EntityManagerFactory 使用完后,我们需要调用它的 close 方法来释放相应的资源。获取、使用 EntityManagerFactory 的实际例子请参考 清单 4 AnimalDAOImpl.java 中的源代码。
获取 EntityManager
要访问 OpenJPA 容器中的实体类,必须首先获得相应的 EntityManager。可以通过 EntityManagerFactory 对象的 createEntityManager() 方法来获取 EntityManager 对象。获取、使用 EntityManager 的实际例子请参考 清单 4 AnimalDAOImpl.java 中的源代码。
EntityTransaction的启动(提交)
对于 OpenJPA 容器中的持久化对象的创建、修改、删除操作必须在代码中显式的处理事务,而对于查询操作则不需要在代码中显式的处理事务。JPA 应用中的事务由 EntityTransaction 接口处理,EntityTransaction 可以直接通过 EntityManager 对象的 getTransaction 方法获得。我们可以调用 EntityTransaction 的 begin(commit) 方法显式的启动(提交)事务。获取、使用 EntityTransaction 的实际例子请参考 清单 4 AnimalDAOImpl.java 中的源代码。
Query 接口和 JPQL 查询语言
要查询 EntityManager 中符合条件的对象列表,需要借助 Query 接口和 JPQL。Query 接口可以直接通过 EntityManager 的 createQuery 方法获得。Query 对象目前支持 JPQL 和原生态 SQL 两种方式。
JPQL 是 OpenJPA 中支持的对象查询语言,是 EJB SQL 的一种实现。通过 JPQL,我们可以用一种面向对象的方式编写持久化对象的查询条件。比如要查找编号为“1”的 Animal 对象,我们可以使用下面的 JPQL 语法:
select animal form Animal animal where animal.id=1)
关于 JPQL 的更多信息请参考 OpenJPA 的帮助文档。Query 接口和 JPQL 的实际例子请参考 清单 4 AnimalDAOImpl.java 中的源代码。
清单 4 中列出了如何使用 OpenJPA 操作、查找持久化对象 Animal 的源代码,读者可以从中了解使用 OpenJPA 时所应该完成的步骤和方法。
清单 4 AnimalDAOImpl.java
2.
3. import java.util.List;
4.
5. import javax.persistence.EntityManager;
6. import javax.persistence.EntityManagerFactory;
7. import javax.persistence.Persistence;
8. import javax.persistence.Query;
9.
10. import org.vivianj.openjpa.dao.AnimalDAO;
11. import org.vivianj.openjpa.entity.Animal;
12.
13. /**
14. * AnimalDAOImpl 演示了如何使用OpenJPA访问数据库的方法和步骤
15. *
16. */
17. public class AnimalDAOImpl implements AnimalDAO {
18.
19. /**
20. * removeAnimal方法可以从数据库中删除指定编号的Animal对象
21. *
22. * @param id
23. * Animal对象的编号
24. */
25. public void removeAnimal(int id) {
26. // 获取EntityManagerFactory
27. EntityManagerFactory factory = Persistence
28. .createEntityManagerFactory("mysql");
29. // 获取EntityManager
30. EntityManager em = factory.createEntityManager();
31. // 开始事务处理
32. em.getTransaction().begin();
33.
34. // 使用Query删除对象
35. em.createQuery("delete from Animal animal where animal.id=" + id)
36. .executeUpdate();
37.
38. // 我们还可以选择通过Query对象来完成
39. /*
40. * // 从EntityManager中查询到符合条件的对象 Animal animal =
41. * em.find(Animal.class,id); // 调用EntityManager的remove方法删除对象
42. * em.remove(animal);
43. */
44.
45. // 提交事务
46. em.getTransaction().commit();
47. // 关闭EntityManager
48. em.close();
49. // 关闭EntityManagerFactory
50. factory.close();
51.
52. }
53.
54. /**
55. * findAnimalsByName 通过输入的name内容模糊查找符合条件的Animal对象列表
56. *
57. * @param name
58. * Animal对象的name
59. * @return 符合模糊查找条件的Animal对象列表
60. */
61. public List<Animal> findAnimalsByName(String name) {
62. // 获取EntityManagerFactory
63. EntityManagerFactory factory = Persistence
64. .createEntityManagerFactory("mysql");
65. // 获取EntityManager
66. EntityManager em = factory.createEntityManager();
67.
68. /*
69. * 通过EntityManager的createQuery方法获取Query对象
70. * createQuery方法的参数是JPQL查询语句,JPQL语句的语法请参考OpenJPA的帮助文档.
71. *
72. * 由于查询不需要事务的支持,因此Query操作的前后没有出现begin、commit方法的调用
73. *
74. */
75. Query q = em
76. .createQuery("select animal from Animal animal where animal.name like '%"
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
77. + name + "%' ESCAPE ''");
78. List<Animal> l = q.getResultList();
79. // 关闭EntityManager
80. em.close();
81. // 关闭EntityManagerFactory
82. factory.close();
83.
84. return l;
85. }
86.
87. /**
88. * getAnimalByPrimaryKey 方法可以查找符合条件的单个Animal对象,
* 如果不存在对应的Animal对象将返回null
89. *
90. * @param id
91. * Animal对象的编号
92. * @return 唯一符合条件的Animal对象
93. *
94. */
95. public Animal getAnimalByPrimaryKey(int id) {
96. // 获取EntityManagerFactory
97. EntityManagerFactory factory = Persistence
98. .createEntityManagerFactory("mysql");
99. // 获取EntityManager
100. EntityManager em = factory.createEntityManager();
101.
102. // 查找符合条件的对象
103. Animal animal = em.find(Animal.class, id);
104.
105. // 关闭EntityManager
106. em.close();
107. // 关闭EntityManagerFactory
108. factory.close();
109.
110. return animal;
111. }
112.
113. /**
114. * 将对象持久化到数据库中
115. *
116. * @param animal
117. * 需要被持久化的对象
118. */
119. public void persistAnimal(Animal animal) {
120. // 获取EntityManagerFactory
121. EntityManagerFactory factory = Persistence
122. .createEntityManagerFactory("mysql");
123. // 获取EntityManager
124. EntityManager em = factory.createEntityManager();
125. // 开始事务处理
126. em.getTransaction().begin();
127.
128. // 持久化对象
129. em.persist(animal);
130.
131. // 提交事务
132. em.getTransaction().commit();
133. // 关闭EntityManager
134. em.close();
135. // 关闭EntityManagerFactory
136. factory.close();
137. }
138.
139. /**
140. * 将Animal对象被更新的属性持久化到数据库中
141. *
142. * @param animal
143. * 被更新过的Animal对象
144. */
145. public void updateAnimal(Animal animal) {
146. // 获取EntityManagerFactory
147. EntityManagerFactory factory = Persistence
148. .createEntityManagerFactory("mysql");
149. // 获取EntityManager
150. EntityManager em = factory.createEntityManager();
151. // 开始事务处理
152. em.getTransaction().begin();
153.
154. // 更新持久化对象状态
155. em.merge(animal);
156.
157. // 提交事务
158. em.getTransaction().commit();
159. // 关闭EntityManager
160. em.close();
161. // 关闭EntityManagerFactory
162. factory.close();
163.
164. }
165.
166. }
总结
本文中首先描述了如何准备 OpenJPA 开发环境所需要的支持环境,接着说明了 OpenJPA 下载、安装的步骤。随后,通过一个简单的例子,讲解了如何应用 OpenJPA 开发 EJB 3.0 应用的步骤和方法,并且通过合适的代码演示了如何使用 JPA 标准接口访问持久化对象。
相关内容下载:OpenJPAExamples.zip