Java Persistence API:用于對象持久化的 API
Java EE 5.0 平臺標(biāo)準(zhǔn)的 ORM 規(guī)范,使得應(yīng)用程序以統(tǒng)一的方式訪問持久層
1. JPA 概述
架構(gòu)圖:
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 開始兼容 JPAOpenJPA
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 文件名稱固定
- 需要配置連接數(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*