一、JPA 入門

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

1. JPA 概述

架構(gòu)圖:

繪圖1.png

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

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

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

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

  • 從功能上來說缔刹, JPA 是 Hibernate 功能的一個子集

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

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

  • OpenJPA
    OpenJPA 是 Apache 組織提供的開源項目

  • TopLink
    TopLink 以前需要收費球涛,如今開源了,Oracle 公司的項目

JPA 的優(yōu)勢:

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

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

  • 可媲美JDBC的查詢能力: JPA的查詢語言是面向?qū)ο蟮暮灏琂PA定義了獨特的JPQL,而且能夠支持批量更新和修改煌张、JOIN呐赡、GROUP BY、HAVING 等通常只有 SQL 才能夠提供的高級查詢特性骏融,甚至還能夠支持子查詢链嘀。

  • 支持面向?qū)ο蟮母呒壧匦? JPA 中能夠支持面向?qū)ο蟮母呒壧匦裕珙愔g的繼承档玻、多態(tài)和類之間的復(fù)雜關(guān)系怀泊,最大限度的使用面向?qū)ο蟮哪P?/p>

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

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

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

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

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

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

    <dependencies>
        <!--配置 HIBERNATE JPA 實現(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, 在這個文件中配置持久化單元

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

圖片.png

  • 需要配置連接數(shù)據(jù)庫信息
  • 需要指定 JPA 使用哪個持久化的框架以及配置該框架的基本屬性
  • 需要指定持久化的實體類
<?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 配置 實現(xiàn) JPA 的 ORM 持久化框架-->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
       <!-- properties 定義連接數(shù)據(jù)庫信息-->
        <properties>
            <!-- jpa中連接數(shù)據(jù)庫 -->
            <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)建持久化實體類

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 測試

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 對象 類似于 Hibernate 中 sessionFactory 對象
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("helloJpa");
        // 創(chuàng)建 EntityManager 對象 類似于 Hibernate 中的 Session 對象
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        // 開啟事務(wù)
        entityManager.getTransaction().begin();

        // 持久化實體操作
        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ù)庫中的表名 跟 該持久化類進(jìn)行關(guān)聯(lián)模孩,可以不配,默認(rèn)關(guān)聯(lián)的以實體類的類名對應(yīng)的表烘豹。
 * Table 注解: 如果數(shù)據(jù)庫中沒有表瓜贾,使用該注解,定義自動創(chuàng)建表的時候的表名
 *
 * ID 注解 : 定義標(biāo)識屬性
 * GeneratedValue 注解: 描述主鍵的生成的策略
 *          JPA  使用 GenerationType 該枚舉類型定義了 4 種 生成策略:
 *              AUTO: 底層是否支持自增長或者序列
 *              IDENTITY:必須 數(shù)據(jù)庫支持 自增長策略携悯。 mysql
 *              SEQUENCE:支持序列的數(shù)據(jù)庫祭芦,oracle :HIBERNATE_SEQ
 *              TABLE: hibernate 自動創(chuàng)建一個 Table 來保存主鍵值。
 *
 * SequenceGenerator 注解:定義創(chuàng)建序列的規(guī)則
 *
 *
 * Column 注解: 定義對應(yīng)的表的字段的名稱憔鬼,約束的規(guī)則(定義長度龟劲,唯一....),該注解可以不配,不配默認(rèn)使用實體屬性名稱作為表的列名稱
 *
 *
 * Temporal 注解:定義表中日期的列采用具體的日期類型轴或。
 *      JPA 使用 TemporalType 該枚舉類型 定義了 3z 中 數(shù)據(jù)庫日期類型:
 *          date:帶年月日
 *          time:帶時分秒
 *          TIMESTAMP:帶年月日時分秒后面的更加精確的時間
 *
 * 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 提供的一個獲取 EntityManagerFactory 對象的工具類
    Persistence.createEntityManagerFactory("helloJpa")

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

  • EntityManager 封裝 CRUD 基本操作,管理 實體對象狀態(tài),一級緩存萍诱。
    entityManager.persist(order):沒有主鍵的返回值悬嗓,該方法的執(zhí)行也會把一個臨時狀態(tài)的 對象轉(zhuǎn)為受容器管理的 持久化對象。只有在刷新容器或者事務(wù)提交的時候裕坊,才會發(fā) insert 語句到 數(shù)據(jù)庫包竹。
    entityManager.find(OrderModel.class, 1L):返回的是受容器管理的真實的類型的對象,立即加載籍凝。
    entityManager.getReference(OrderModel.class,1l):返回的是受容器管理的真實的類型的對象周瞎,懶加載
    更新操作方式1,使用快照更新:OrderModel orderModel = entityManager.find(OrderModel.class, 1L);
    orderModel.setDescription("通過快照更新饵蒂,沒有顯示的調(diào)用 meger方法");
    更新操作方式2声诸,meger: 傳入?yún)?shù)對象如果是 DO 對象,執(zhí)行完該方法然后是 DO 對象苹享,但是方法執(zhí)行后返回的是 PO 對象双絮。merger 更新的 DO 對象會把更新的數(shù)據(jù)就會覆蓋容器中已經(jīng)存在的要修改的 PO 對象數(shù)據(jù)。merger 的參數(shù)對象是 TO 得问,就會執(zhí)行 insert 操作囤攀。
    entityManager.remove(orderModel):刪除的參數(shù)對象為 PO 對象
    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ù)的查詢支持三種:請看hibernate*

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市漓骚,隨后出現(xiàn)的幾起案子蝌衔,更是在濱河造成了極大的恐慌,老刑警劉巖蝌蹂,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件噩斟,死亡現(xiàn)場離奇詭異,居然都是意外死亡孤个,警方通過查閱死者的電腦和手機(jī)剃允,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來齐鲤,“玉大人斥废,你說我怎么就攤上這事「迹” “怎么了牡肉?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長淆九。 經(jīng)常有香客問我统锤,道長毛俏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任饲窿,我火速辦了婚禮拧抖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘免绿。我一直安慰自己,他們只是感情好擦盾,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布嘲驾。 她就那樣靜靜地躺著,像睡著了一般迹卢。 火紅的嫁衣襯著肌膚如雪辽故。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天腐碱,我揣著相機(jī)與錄音誊垢,去河邊找鬼。 笑死症见,一個胖子當(dāng)著我的面吹牛喂走,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谋作,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼芋肠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了遵蚜?” 一聲冷哼從身側(cè)響起帖池,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吭净,沒想到半個月后睡汹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡寂殉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年囚巴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片不撑。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡文兢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出焕檬,到底是詐尸還是另有隱情姆坚,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布实愚,位于F島的核電站兼呵,受9級特大地震影響兔辅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜击喂,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一维苔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧懂昂,春花似錦介时、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至铲敛,卻和暖如春褐澎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背伐蒋。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工工三, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人先鱼。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓俭正,卻偏偏與公主長得像,于是被迫代替她去往敵國和親焙畔。 傳聞我的和親對象是個殘疾皇子段审,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容