一、JPA 入門

Java Persistence API:用于對(duì)象持久化的 API
Java EE 5.0 平臺(tái)標(biāo)準(zhǔn)的 ORM 規(guī)范,使得應(yīng)用程序以統(tǒng)一的方式訪問持久層

1. JPA 概述

架構(gòu)圖:

繪圖1.png

JPA和Hibernate的關(guān)系:

JPA 是 hibernate 的一個(gè)抽象(就像JDBC和JDBC驅(qū)動(dòng)的關(guān)系):

  • JPA 是規(guī)范:JPA 本質(zhì)上就是一種 ORM 規(guī)范,不是ORM 框架 —— 因?yàn)?JPA 并未提供 ORM 實(shí)現(xiàn),它只是制訂了一些規(guī)范,提供了一些編程的 API 接口,但具體實(shí)現(xiàn)則由 ORM 廠商提供實(shí)現(xiàn)

  • Hibernate 是實(shí)現(xiàn):Hibernate 除了作為 ORM 框架之外,它也是一種 JPA 實(shí)現(xiàn)

  • 從功能上來說, JPA 是 Hibernate 功能的一個(gè)子集

JPA 的實(shí)現(xiàn)(JPA 供應(yīng)商):

  • Hibernate:
    JPA 的開發(fā)者就是 Hibernate 和 EJB 的開發(fā)者
    Hibernate 從 3.2 開始兼容 JPA

  • OpenJPA
    OpenJPA 是 Apache 組織提供的開源項(xiàng)目

  • TopLink
    TopLink 以前需要收費(fèi),如今開源了,Oracle 公司的項(xiàng)目

JPA 的優(yōu)勢(shì):

  • 標(biāo)準(zhǔn)化: 提供相同的 API,這保證了基于JPA 開發(fā)的企業(yè)應(yīng)用能夠經(jīng)過少量的修改就能夠在不同的 JPA 框架下運(yùn)行。

  • 簡(jiǎn)單易用,集成方便: JPA 的主要目標(biāo)之一就是提供更加簡(jiǎn)單的編程模型,在 JPA 框架下創(chuàng)建實(shí)體和創(chuàng)建 Java 類一樣簡(jiǎn)單,只需要使用 javax.persistence.Entity 進(jìn)行注釋;JPA 的框架和接口也都非常簡(jiǎn)單。

  • 可媲美JDBC的查詢能力: JPA的查詢語言是面向?qū)ο蟮?,JPA定義了獨(dú)特的JPQL,而且能夠支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能夠提供的高級(jí)查詢特性,甚至還能夠支持子查詢。

  • 支持面向?qū)ο蟮母呒?jí)特性: JPA 中能夠支持面向?qū)ο蟮母呒?jí)特性,如類之間的繼承、多態(tài)和類之間的復(fù)雜關(guān)系,最大限度的使用面向?qū)ο蟮哪P?/p>

JPA 主要 3 技術(shù)(掌握)

  • ORM 映射元數(shù)據(jù):JPA 支持 XML 和 JDK 5.0 注解兩種元數(shù)據(jù)的形式,元數(shù)據(jù)描述對(duì)象和表之間的映射關(guān)系,框架據(jù)此將實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)表中。

  • JPA 的 API:用來操作實(shí)體對(duì)象,執(zhí)行CRUD操作,框架在后臺(tái)完成所有的事情,開發(fā)者從繁瑣的 JDBC和 SQL代碼中解脫出來。

  • 查詢語言(JPQL):這是持久化操作中很重要的一個(gè)方面,通過面向?qū)ο蠖敲嫦驍?shù)據(jù)庫(kù)的查詢語言查詢數(shù)據(jù),避免程序和具體的 SQL 緊密耦合

2. JPA 持久化對(duì)象開發(fā)步驟:

2.1 導(dǎo)入 HIBERNATE JPA 實(shí)現(xiàn)(配置 POM 文件)

    <dependencies>
        <!--配置 HIBERNATE JPA 實(shí)現(xiàn)包 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.2.12.Final</version>
        </dependency>
    </dependencies>

2.2 創(chuàng)建 persistence.xml, 在這個(gè)文件中配置持久化單元

注意:persistence.xml 放置于 類路徑下的 META-INF 目錄下,persistence.xml 文件名稱固定

圖片.png

  • 需要配置連接數(shù)據(jù)庫(kù)信息
  • 需要指定 JPA 使用哪個(gè)持久化的框架以及配置該框架的基本屬性
  • 需要指定持久化的實(shí)體類
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
    <!--persistence-unit 定義持久化單元:
        name 屬性:定義持久化單元名稱
        transaction-type 屬性:定義事務(wù)類型,此處為本地事務(wù) RESOURCE_LOCAL-->
    <persistence-unit name="helloJpa" transaction-type="RESOURCE_LOCAL">
       <!-- provider 配置 實(shí)現(xiàn) JPA 的 ORM 持久化框架-->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
       <!-- properties 定義連接數(shù)據(jù)庫(kù)信息-->
        <properties>
            <!-- jpa中連接數(shù)據(jù)庫(kù) -->
            <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@192.168.0.112:1521:XE" />
            <property name="javax.persistence.jdbc.user" value="ZHANGJIAN" />
            <property name="javax.persistence.jdbc.password" value="zhangjian"></property>

            <!-- jpa中配置hibernate基本屬性 -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
          <!--  <property name="hibernate.hbm2ddl.auto" value="update" />-->
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
        </properties>
    </persistence-unit>
</persistence>

2.3 創(chuàng)建持久化實(shí)體類

package org.zj.jpa.demo.entity;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;

/**
 * Created by ZhangJian on 2018/1/17.
 */
@Entity
@Table(name = "t_order")
public class OrderEntity {
    @Id
    @SequenceGenerator(name="seq_name",sequenceName = "order_seq",allocationSize = 1)
    @GeneratedValue(generator = "seq_name")
    private Long id;
    private String description;
    private BigDecimal totalMoney;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createOrderTime;
    private Integer state;

2.4 測(cè)試

package org.zj.jpa.demo.test;

import org.zj.jpa.demo.entity.OrderEntity;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;

/**
 * Created by ZhangJian on 2018/1/17.
 */
public class App {
    public static void main(String[] args) {

        // 創(chuàng)建 EntityManagerFactory 對(duì)象 類似于 Hibernate 中 sessionFactory 對(duì)象
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("helloJpa");
        // 創(chuàng)建 EntityManager 對(duì)象 類似于 Hibernate 中的 Session 對(duì)象
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        // 開啟事務(wù)
        entityManager.getTransaction().begin();

        // 持久化實(shí)體操作
        OrderEntity order =  new OrderEntity();
        order.setCreateOrderTime(new Timestamp(new Date().getTime()));
        order.setDescription("田雞又肚子疼");
        order.setState(1);
        order.setTotalMoney(new BigDecimal(2000));

        entityManager.persist(order);


        // 提交事務(wù)
        entityManager.getTransaction().commit();
        entityManager.close();
        entityManagerFactory.close();

    }
}

3.注解元數(shù)據(jù)介紹

/**
 * Entity 注解: 定義該類為持久化類
 *      name 屬性:定義數(shù)據(jù)庫(kù)中的表名 跟 該持久化類進(jìn)行關(guān)聯(lián),可以不配,默認(rèn)關(guān)聯(lián)的以實(shí)體類的類名對(duì)應(yīng)的表。
 * Table 注解: 如果數(shù)據(jù)庫(kù)中沒有表,使用該注解,定義自動(dòng)創(chuàng)建表的時(shí)候的表名
 *
 * ID 注解 : 定義標(biāo)識(shí)屬性
 * GeneratedValue 注解: 描述主鍵的生成的策略
 *          JPA  使用 GenerationType 該枚舉類型定義了 4 種 生成策略:
 *              AUTO: 底層是否支持自增長(zhǎng)或者序列
 *              IDENTITY:必須 數(shù)據(jù)庫(kù)支持 自增長(zhǎng)策略。 mysql
 *              SEQUENCE:支持序列的數(shù)據(jù)庫(kù),oracle :HIBERNATE_SEQ
 *              TABLE: hibernate 自動(dòng)創(chuàng)建一個(gè) Table 來保存主鍵值。
 *
 * SequenceGenerator 注解:定義創(chuàng)建序列的規(guī)則
 *
 *
 * Column 注解: 定義對(duì)應(yīng)的表的字段的名稱,約束的規(guī)則(定義長(zhǎng)度,唯一....),該注解可以不配,不配默認(rèn)使用實(shí)體屬性名稱作為表的列名稱
 *
 *
 * Temporal 注解:定義表中日期的列采用具體的日期類型。
 *      JPA 使用 TemporalType 該枚舉類型 定義了 3z 中 數(shù)據(jù)庫(kù)日期類型:
 *          date:帶年月日
 *          time:帶時(shí)分秒
 *          TIMESTAMP:帶年月日時(shí)分秒后面的更加精確的時(shí)間
 *
 * Transient 注解:指定修飾的屬性,不作為表中的列。忽略該屬性
 */
@Entity
@Table(name = "t_order")
public class OrderModel {

    @Id
    @GeneratedValue(generator = "order_seq")
    @SequenceGenerator(name = "order_seq",sequenceName = "order_seq",allocationSize = 1)
    private Long id;

    private String description;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createOrdTime;
    private Integer state;
    private Double totalMoney;

    @Transient
    private  String noCreateColumn;

4. JPA 常用 API

  • Persistence:JPA 提供的一個(gè)獲取 EntityManagerFactory 對(duì)象的工具類
    Persistence.createEntityManagerFactory("helloJpa")

  • EntityManagerFactory JPA 應(yīng)用中只有一份,通過它創(chuàng)建 EntityManager 對(duì)象。

  • EntityManager 封裝 CRUD 基本操作,管理 實(shí)體對(duì)象狀態(tài),一級(jí)緩存。
    entityManager.persist(order):沒有主鍵的返回值,該方法的執(zhí)行也會(huì)把一個(gè)臨時(shí)狀態(tài)的 對(duì)象轉(zhuǎn)為受容器管理的 持久化對(duì)象。只有在刷新容器或者事務(wù)提交的時(shí)候,才會(huì)發(fā) insert 語句到 數(shù)據(jù)庫(kù)。
    entityManager.find(OrderModel.class, 1L):返回的是受容器管理的真實(shí)的類型的對(duì)象,立即加載。
    entityManager.getReference(OrderModel.class,1l):返回的是受容器管理的真實(shí)的類型的對(duì)象,懶加載
    更新操作方式1,使用快照更新:OrderModel orderModel = entityManager.find(OrderModel.class, 1L);
    orderModel.setDescription("通過快照更新,沒有顯示的調(diào)用 meger方法");
    更新操作方式2,meger: 傳入?yún)?shù)對(duì)象如果是 DO 對(duì)象,執(zhí)行完該方法然后是 DO 對(duì)象,但是方法執(zhí)行后返回的是 PO 對(duì)象。merger 更新的 DO 對(duì)象會(huì)把更新的數(shù)據(jù)就會(huì)覆蓋容器中已經(jīng)存在的要修改的 PO 對(duì)象數(shù)據(jù)。merger 的參數(shù)對(duì)象是 TO ,就會(huì)執(zhí)行 insert 操作。
    entityManager.remove(orderModel):刪除的參數(shù)對(duì)象為 PO 對(duì)象
    entityManager.createQuery("from OrderModel "):創(chuàng)建 Quqery 接口,需要出入 JPQL 語句。

  • Quqery 接口 API:
    query.getResultList():查詢記錄使用 List 封裝。
    query.getSingleResult(): 查詢當(dāng)行記錄
    setFirstResult(0): 設(shè)置開始下標(biāo)
    setMaxResults(1):設(shè)置抓取記錄條數(shù)
    jpql 帶參數(shù)的查詢支持三種:請(qǐng)看hibernate*

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容