天天看點

JPA入門

原文釋出于: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隻會使用第一個。