JPA入門

原文發佈於:http://www.gufeng.tech/  穀風的我的主頁java

    JPA全稱Java Persistence API即Java持久化API,是一種經過註解或者XML配置描述映射關係來實現將實體持久化到數據庫的一種java持久化實現方案。JPA和JDBC同樣,都是jdk提供的API,各廠商提供實現,目前的實現有Apache的OpenJPA以及應用普遍的Hibernate,固然還有其它的實現,這裏就不一一列出了。JAP做爲一種標準,已經得到了JavaEES容器的支持,同時也仍然能夠在JavaSE環境中使用,這就奠基了它可被普遍應用的前提。mysql


    JPA在隨着SpringBoot的默認支持,再次被普遍說起、應用。做爲一種ORM的技術,除了擁有ORM的特色以外,還有一些它本身的特色:程序員

1 標準化web

JPA是java標準化組織JCP提出的一項持久化標準,因此其任何實現都提供了相同的API,即使更換了實現方案,兼容性也是很是好的。sql

2 更面向對象數據庫

JPA支持面向對象中的繼承、多態及多個類間的關聯關係,所以使得程序員在使用JPA開發時能夠方便的使用面向對象的思惟,過渡性比較好。併發

3 功能全面框架

JPA支持事務、併發等特性,而不只僅是一個簡單的持久化框架,於是能夠在實際使用中發揮更大的做用。ide

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、一對多、多對多等關係)轉移到程序中。這會帶來如下一些問題:

1 程序可讀性差,若是遇到特別複雜的業務邏輯,那麼對於實體的定義也會很是困難,這須要設計者具備很是高的抽象、規範、設計能力。

2 數據關係發生變化時,實體必然也會發生變化。

3 將關係型數據庫映射到面向對象程序上,自己就有着深度的複雜性,二者關注點不一樣,當關聯到一塊兒的時候必然會來帶衝突。數據庫關心的是數據以及數據的完整性;面向對象關心的是對象的成員及行爲。


接下來介紹下JPA的一些核心類:

1 EntityManagerFactory

    EntityManagerFactory 是 EntityManager 的工廠類,負責建立 EntityManager 對象。

2 EntityManager

    EntityManager 是 JPA 應用中使用的基本對象,經過它提供的相應方法能夠管理持久化對象,也能夠新建或者刪除持久化對象。EntityManager 還負責建立 Query 實例。在容器外使用時,EntityManagerFactory 和 EntityManager 之間是一對一的關係。

EntityTransaction

    EntityTransaction 提供 Entity 操做時須要的事務管理,和 EntityManager 是一對一的關係。在查詢操做時不須要使用 EntityTransaction,而在對象持久化、狀態更新、對象刪除等狀況下則必須使用顯式的使用 EntityTransaction 的相關方法管理事務。

4 Query

    Query 是查詢實體的接口,Query 對象能夠從 EntityManager 中得到。根據 EJB 3.0 規範中的描述,Query 接口須要同時支持 JPQL 和原生態 SQL 兩種語法。

5 Persistence

    Persistence 是一個工具類,負責根據配置文件提供的參數建立 EntityManagerFactory 對象。


最後看一段JPA的示例代碼:

import javax.persistence.Column;  
import javax.persistence.Entity;  
import javax.persistence.Id;  
import javax.persistence.Table;  
  
@Entity  
@Table(name = "user")  
public class User {  
    @Id  
    @Column(name = "id")  
    private String id;  
  
    @Column(name = "name")  
    private String name;  
  
    public String getId() {  
        return id;  
    }  
  
    public void setId(String id) {  
        this.id = id;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
   
}
import javax.persistence.EntityManager;  
import javax.persistence.EntityManagerFactory;  
import javax.persistence.Persistence;  
import java.util.List;  
  
public class Main {  
    static EntityManagerFactory emf = Persistence.createEntityManagerFactory("gufengJPA");  
    static EntityManager em = emf.createEntityManager();  
  
    public static void main(String[] args) {  
        User person = new User();   
        person.setId(123456l);  
        person.setName("張無忌");  
        em.persist(person);  
  
        add(person);  
  
        System.out.println("user id:" + person.getId());  
        User user = find(person.getId());  
        System.out.println(user);  
  
        List<User> all = findAll();  
        for (User u : all) {  
            System.out.println(u);  
        }  
  
        em.close();  
        emf.close();  
    }  
   
    public static void add(User user) {  
        em.getTransaction().begin();  
        em.persist(user);  
        em.getTransaction().commit();  
    }  
   
    public static User find(Object id) {  
        User user = em.find(User.class, id);  
        return user;  
    }  
  
    public static List<User> findAll() {  
        List<User> users = em.createQuery("select u from User u")  
                .getResultList();  
        return users;  
    }  
}
<?xml version="1.0" encoding="UTF-8"?>  
<persistence version="2.0"  
             xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  
             http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">  
    <!-- 持久化單元 -->  
    <persistence-unit name="gufengJPA" transaction-type="RESOURCE_LOCAL">  
        <!--能夠指定,若是不指定則從META-INF/services加載-->  
        <!--<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>-->  
        <!-- <class>com.micmiu.hibernate.jpa.UserInfo</class> -->  
        <!--<provider>com.tongweb.openjpa.persistence.PersistenceProviderImpl</provider>-->  
        <!--<jta-data-source>MyDataSource</jta-data-source>-->  
        <!-- class 定義指定持久化的實體類 注意配置屬性hibernate.archive.autodetection=false -->  
        <!--<class>jpa.User</class>-->  
        <properties>  
            <property name="hibernate.archive.autodetection" value="class,hbm"/>  
  
            <!--Hibernate 方言 -->  
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>  
  
            <!--數據庫url -->  
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test"/>  
            <!--數據庫驅動 -->  
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>  
            <!--配置數據庫用戶名 -->  
            <property name="hibernate.connection.username" value="root"/>  
            <!--配置數據庫密碼 -->  
            <property name="hibernate.connection.password" value="123456"/>  
  
            <!--設置外鏈接抓取樹的最大深度 -->  
            <!--<property name="hibernate.max_fetch_depth" value="3"/>-->  
            <!--自動輸出schema建立DDL語句 -->  
            <!--<property name="hibernate.hbm2ddl.auto" value="update"/>-->  
  
            <property name="hibernate.show_sql" value="true"/>  
  
        </properties>  
    </persistence-unit>  
</persistence>

    這裏須要注意的是JPA配置文件persistence.xml 必需放到類路徑的根路徑的META-INF文件夾下。

   

Persistence.createEntityManagerFactory("gufengJPA");

    上面這行代碼是經過Java的SPI機制得到具體實現的。在hibernate的jar包裏有個META-INF/services/javax.persistence.spi.PersistenceProvider 文件,這裏指定的實現爲 org.hibernate.jpa.HibernatePersistenceProvider。再有多個的時候,Persistence只會使用第一個。

相關文章
相關標籤/搜索