原文发布于:http://www.gufeng.tech/ 谷风的个人主页
JPA全称Java Persistence API即Java持久化API,是一种通过注解或者XML配置描述映射关系来实现将实体持久化到数据库的一种java持久化实现方案。JPA和JDBC一样,都是jdk提供的API,各厂商提供实现,目前的实现有Apache的OpenJPA以及应用广泛的Hibernate,当然还有其它的实现,这里就不一一列出了。JAP作为一种标准,已经获得了JavaEES容器的支持,同时也仍然可以在JavaSE环境中使用,这就奠定了它可被广泛应用的前提。
JPA在随着SpringBoot的默认支持,再次被广泛提及、应用。作为一种ORM的技术,除了拥有ORM的特点之外,还有一些它自己的特点:
1 标准化
JPA是java标准化组织JCP提出的一项持久化标准,所以其任何实现都提供了相同的API,即便更换了实现方案,兼容性也是非常好的。
2 更面向对象
JPA支持面向对象中的继承、多态及多个类间的关联关系,因此使得程序员在使用JPA开发时可以方便的使用面向对象的思维,过渡性比较好。
3 功能全面
JPA支持事务、并发等特性,而不仅仅是一个简单的持久化框架,因而可以在实际使用中发挥更大的作用。
4 卓越的查询能力
JPA是面向对象的,定义了JPQL(Java Persistence Query Language),JPQL是一种针对实体的查询语句,操作对象是实体,可以以面向对象的方式构造查询语句,在这点上类似Hibernate的HQL。JPQL能够支持批量操作(如更新和修改)、join、group by、having等子句,同时还支持子查询,因此其查询能力可见一斑。
5 集成方便
这一点从SpringBoot选择了JPA就能够看出来。在JPA框架下创建实体只需要使用javax.persistence.Entity注解即可,其接口使用也非常简单容易上手,尤其重要的一点是JPA被设计成非入侵式的,天然注定了它能够被非常容易的集成。
JPA涉及的技术
1 元数据
关于映射关系,JPA同时支持注解和XML。
2 API
操作简单,将程序员从繁琐的SQL中解放出来。
3 查询语言
通过面向对象的方式进行数据查询,避免程序与SQL语句的的耦合。
上面提及了JPA的各种好处,那么作为一种技术方案(或者叫规范),JPA有没有缺点呢?答案是肯定的,JPA将数据库关系以实体及实体间关系表示,必然存在一种将数据库的复杂概念(如一对一、一对多、多对多等关系)转移到程序中。这会带来以下一些问题:
1 程序可读性差,如果遇到特别复杂的业务逻辑,那么对于实体的定义也会非常困难,这需要设计者具有非常高的抽象、规范、设计能力。
2 数据关系发生变化时,实体必然也会发生变化。
3 将关系型数据库映射到面向对象程序上,本身就有着深度的复杂性,两者关注点不同,当关联到一起的时候必然会来带冲突。数据库关心的是数据以及数据的完整性;面向对象关心的是对象的成员及行为。
接下来介绍下JPA的一些核心类:
1 EntityManagerFactory
EntityManagerFactory 是 EntityManager 的工厂类,负责创建 EntityManager 对象。
2 EntityManager
EntityManager 是 JPA 应用中使用的基本对象,通过它提供的相应方法可以管理持久化对象,也可以新建或者删除持久化对象。EntityManager 还负责创建 Query 实例。在容器外使用时,EntityManagerFactory 和 EntityManager 之间是一对一的关系。
3 EntityTransaction
EntityTransaction 提供 Entity 操作时需要的事务管理,和 EntityManager 是一对一的关系。在查询操作时不需要使用 EntityTransaction,而在对象持久化、状态更新、对象删除等情况下则必须使用显式的使用 EntityTransaction 的相关方法管理事务。
4 Query
Query 是查询实体的接口,Query 对象可以从 EntityManager 中获得。根据 EJB 3.0 规范中的描述,Query 接口需要同时支持 JPQL 和原生态 SQL 两种语法。
5 Persistence
Persistence 是一个工具类,负责根据配置文件提供的参数创建 EntityManagerFactory 对象。
最后看一段JPA的示例代码:
这里需要注意的是JPA配置文件persistence.xml 必需放到类路径的根路径的META-INF文件夹下。
上面这行代码是通过Java的SPI机制获得具体实现的。在hibernate的jar包里有个META-INF/services/javax.persistence.spi.PersistenceProvider 文件,这里指定的实现为 org.hibernate.jpa.HibernatePersistenceProvider。再有多个的时候,Persistence只会使用第一个。