JPA 体系架构
JPA 中定义一套类和接口用于实现持久化管理和对象/关系的映射,下面这张图中显示了 JPA 的主要组件以及它们之间的相互关系。
图1 JPA 主要组件和相互关系
EntityManagerFactory
EntityManagerFactory 是 EntityManager 的工厂类,负责创建 EntityManager 对象。
EntityManager
EntityManager 是 JPA 应用中使用的基本对象,通过它提供的相应方法可以管理持久化对象,也可以新建或者删除持久化对象。EntityManager 还负责创建 Query 实例。在容器外使用时,EntityManagerFactory 和 EntityManager 之间是一对一的关系。
Entity
EntityTransaction 提供 Entity 操作时需要的事务管理,和 EntityManager 是一对一的关系。在查询操作时不需要使用 EntityTransaction,而在对象持久化、状态更新、对象删除等情况下则必须使用显式的使用 EntityTransaction 的相关方法管理事务。
Query
Query 是查询实体的接口,Query 对象可以从 EntityManager 中获得。根据 EJB 3.0 规范中的描述,Query 接口需要同时支持 JPQL 和原生态 SQL 两种语法。
Persistence
Persistence 是一个工具类,负责根据配置文件提供的参数创建 EntityManagerFactory 对象。
下面的代码演示了如何通过 JPA 提供的接口和 JPQL 查询语言完成实体查询和更新的例子,例子中的代码假定运行在非 Java EE 环境中。
清单 1 在非 Java EE 环境使用 JPA 接口的例子
2 * Persistence 类获取 EntityManagerFactory 实例;
3 * 一般 EntityManagerFactory 实例被缓存起来重复使用,
4 * 避免重复创建 EntityManagerFactory 实例引起的性能影响
5 */
6 EntityManagerFactory factory =
7 Persistence.createEntityManagerFactory (“mysql”);
8
9 // 从 EntityManagerFactory 实例 factory 中获取 EntityManager
10 EntityManager em = factory.
11 createEntityManager(PersistenceContextType.EXTENDED);
12
13 // 实体的更新需要在事务中运行
14 EntityTransaction tx = em.getTransaction ();
15 tx.begin ();
16
17 // 查找所有公司中的女性雇员
18 Query query = em.createQuery ("select e from Employee e "
19 + " where e.sex = 'femail'");
20 List results = query.getResultList ();
21
22 // 给所有女性雇员增加半天假期
23 for (Object res : results){
24 Employee emp = (Employee) res;
25 emp.setHoliday (emp.getHoliday () +0.5);}
26
27 // 提交事务(持久化所有更新)
28 tx.commit ();
29 em.close ();
30 factory.close ();
31
下面的代码显示了在 EJB 容器中开发 JPA 应用时的接口使用情况,由于容器中的 EntityManager 是注入的,事务也是声明式的,因此在容器中完成上面的业务逻辑要简单得多。
清单 2 在容器中运行的 JPA 例子
2. * 在容器中运行 JPA 应用时,EntityManager 接口的实例”em”
3. * 是通过 @Resource 注释注入的。事务也通常是声明式的。
4. */
5. // 查找所有公司中的女性雇员
6. Query query = em.createQuery ("select e from Employee e "
7. + " where e.sex = 'femail'");
8. List results = query.getResultList ();
9.
10. // 给所有女性雇员增加半天假期
11. for (Object res : results){
12. Employee emp = (Employee) res;
13. emp.setHoliday (emp.getHoliday () +0.5);}
JPA 的优势
JPA 标准制定过程中充分吸收了目前已经出现的所有持久化技术的所有优点,摒弃了它们存在的局限,使 JPA 在简单易用、查询能力等方面表现突出。
标准化
JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问 API,这保证了基于 JPA 开发的企业应用能够经过少量的修改就能够在不同的 JPA 框架下运行。
对容器级特性的支持
JPA 框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。
简单易用,集成方便
JPA 的主要目标之一就是提供更加简单的编程模型:在 JPA 框架下创建实体和创建 Java 类一样简单,没有任何的约束和限制,只需要使用 javax.persistence.Entity 进行注释;JPA 的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握。JPA 基于非侵入式原则设计,因此可以很容易的和其它框架或者容器集成。
可媲美 JDBC 的查询能力
JPA 定义了独特的 JPQL(Java Persistence Query Language),JPQL 是 EJB QL 的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
支持面向对象的高级特性
JPA 中能够支持面向对象的高级特性,比如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。
下面的这个表格中列出了当前常用持久化技术的优缺点。
表 1 持久化技术的优缺点
支持内容: | 序列化 | JDBC | ORM | ODB | EJB 2.X | JDO | EJB 3 (JPA) |
---|---|---|---|---|---|---|---|
Java 对象 | Yes | No | Yes | Yes | Yes | Yes | Yes |
高级 OO 原理 | Yes | No | Yes | Yes | No | Yes | Yes |
事务完整性 | No | Yes | Yes | Yes | Yes | Yes | Yes |
并发 | No | Yes | Yes | Yes | Yes | Yes | Yes |
大数据集 | No | Yes | Yes | Yes | Yes | Yes | Yes |
现有 Schema | No | Yes | Yes | No | Yes | Yes | Yes |
关系型和非关系型数据存储 | No | No | No | No | Yes | Yes | No |
查询 | No | Yes | Yes | Yes | Yes | Yes | Yes |
严格的标准 / 可移植 | Yes | No | No | No | Yes | Yes | Yes |
简单易用 | Yes | Yes | Yes | Yes | No | Yes | Yes |