文章目錄
1. 什麼是JPA
JPA的全稱是Java Persistence API,即Java持久化API,是SUN公司推出的一套基於ORM的規範,內部是由一系列的接口和抽象類構成。
ORM(Object-Relational Mapping):表示對象關係映射。在面向對象的軟件開發中,通過ORM,就可以把對象映射到關係型數據庫中。只要有一套程序能夠做到建立對象與數據庫的關聯,操作對象就可以直接操作數據庫數據,就可以說這套程序實現了ORM對象關係映射。簡單的說,ORM就是建立實體類和數據庫表之間的關係,從而達到操作實體類就相當於操作數據庫表的目的。
JPA與Hibernate的關係:JPA規範本質上就是一種ORM規範,注意不是ORM框架,因爲JPA並未提供ORM實現,它只是制訂了一些規範,提供了一些編程的API接口,但具體實現則由服務廠商來提供實現。JPA和Hibernate的關係就像JDBC和JDBC驅動的關係,JPA是規範,Hibernate除了作爲ORM框架之外,它也是一種JPA實現。JPA怎麼取代Hibernate呢?JDBC規範可以驅動底層數據庫嗎?答案是否定的,也就是說,如果使用JPA規範進行數據庫操作,底層需要hibernate作爲其實現類完成數據持久化工作。
2. JPA快速入門
2.1 創建表結構
CREATE TABLE cst_customer (
cust_id bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客戶編號(主鍵)',
cust_name varchar(32) NOT NULL COMMENT '客戶名稱(公司名稱)',
cust_source varchar(32) DEFAULT NULL COMMENT '客戶信息來源',
cust_industry varchar(32) DEFAULT NULL COMMENT '客戶所屬行業',
cust_level varchar(32) DEFAULT NULL COMMENT '客戶級別',
cust_address varchar(128) DEFAULT NULL COMMENT '客戶聯繫地址',
cust_phone varchar(64) DEFAULT NULL COMMENT '客戶聯繫電話',
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2.2 編寫實體類
@Entity //聲明實體類
@Table(name="cst_customer") //建立實體類和表的映射關係
public class Customer {
@Id //聲明當前私有屬性爲主鍵
@GeneratedValue(strategy=GenerationType.IDENTITY) //配置主鍵的生成策略
@Column(name="cust_id") //指定和表中cust_id字段的映射關係
private Long custId;
@Column(name="cust_name") //指定和表中cust_name字段的映射關係
private String custName;
@Column(name="cust_source") //指定和表中cust_source字段的映射關係
private String custSource;
@Column(name="cust_industry") //指定和表中cust_industry字段的映射關係
private String custIndustry;
@Column(name="cust_level") //指定和表中cust_level字段的映射關係
private String custLevel;
@Column(name="cust_address") //指定和表中cust_address字段的映射關係
private String custAddress;
@Column(name="cust_phone") //指定和表中cust_phone字段的映射關係
private String custPhone;
// 省略 get和 set方法
}
2.3 編寫JPA核心配置文件
在java工程的resources路徑下創建一個名爲META-INF的文件夾,在此文件夾下創建一個名爲persistence.xml的配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<!-- persistence-unit標籤:配置持久化單元
* name:持久化單元名稱
* transaction-type:事務管理的方式
* JTA:分佈式事務管理
* RESOURCE_LOCAL:本地事務管理
-->
<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
<!-- 配置JPA規範的服務提供商 -->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="123456"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql:///joker"/>
<!-- JPA提供者的可選配置:我們的JPA規範的提供者爲 hibernate,所以 JPA的核心配置中兼容 hibernate的配置 -->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
2.4 編寫測試代碼
@Test
public void test() {
//創建實體管理類工廠,藉助 Persistence的靜態方法獲取,其中傳遞的參數爲持久化單元名稱(jpa配置文件中)
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
//創建實體管理類
EntityManager em = factory.createEntityManager();
//獲取事務對象
EntityTransaction tx = em.getTransaction();
//開啓事務
tx.begin();
Customer c = new Customer();
c.setCustName("joker");
//保存操作
em.persist(c);
//提交事務
tx.commit();
//釋放資源
em.close();
factory.close();
}
3. JPA的主鍵生成策略
JPA提供的四種主鍵生成策略爲TABLE、SEQUENCE、IDENTITY、AUTO。具體說明如下:
- IDENTITY:主鍵由數據庫自動生成,底層數據庫必須支持自動增長。
- SEQUENCE:根據底層數據庫的序列來生成主鍵,條件是數據庫支持序列。
- TABLE:JPA提供的一種機制,通過一張數據庫表的形式幫助我們完成主鍵自增。
- AUTO:由程序自動的幫助我們選擇主鍵生成策略。
4. JPA的相關API詳解
-
Persistence對象主要作用是用於獲取EntityManagerFactory對象的,通過調用該類的createEntityManagerFactory靜態方法,根據配置文件中持久化單元名稱創建EntityManagerFactory。
-
EntityManagerFactory接口主要用來創建EntityManager實例。由於EntityManagerFactory是一個線程安全的對象,並且EntityManagerFactory的創建極其浪費資源,所以在使用JPA編程時,我們可以對EntityManagerFactory的創建進行優化,只需要做到一個工程只存在一個EntityManagerFactory即可。
-
EntityManager是完成持久化操作的核心對象。實體類作爲普通java對象,只有在調用EntityManager將其持久化後纔會變成持久化對象。EntityManager對象在一組實體類與底層數據源之間進行O/R映射的管理。它可以用來管理和更新Entity Bean,根椐主鍵查找Entity Bean,還可以通過JPQL語句查詢實體。常用方法說明:
- getTransaction:獲取事務對象
- persist:保存操作
- merge:更新操作
- remove:刪除操作
- find/getReference:根據id查詢
-
EntityTransaction是完成事務操作的核心對象,對於EntityTransaction在我們的java代碼中承接事務相關的功能。
5. JPQL查詢
JPQL全稱Java Persistence Query Language,基於首次在EJB2.0中引入的EJB查詢語言(EJB QL),Java持久化查詢語言(JPQL)是一種可移植的查詢語言,旨在以面向對象表達式語言的表達式,將SQL語法和簡單查詢語義綁定在一起,使用這種語言編寫的查詢是可移植的,可以被編譯成所有主流數據庫服務器上的SQL。其特徵與原生SQL語句類似,並且完全面向對象,通過類名和屬性訪問,而不是表名和表的屬性。
5.1 基本查詢
@Test
public void test() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
EntityManager em = factory.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
String jpql = "from Customer";
Query query = em.createQuery(jpql);
List list = query.getResultList(); //得到集合返回類型
for (Object object : list) {
System.out.println(object);
}
tx.commit();
em.close();
factory.close();
}
5.2 條件查詢
@Test
public void test() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
EntityManager em = factory.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
String jpql = "from Customer where custName like ? ";
Query query = em.createQuery(jpql);
query.setParameter(1, "%張%"); //對佔位符賦值,從 1開始
Object object = query.getSingleResult(); //得到唯一的結果集對象
System.out.println(object);
tx.commit();
em.close();
factory.close();
}
5.3 分頁查詢
@Test
public void test() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
EntityManager em = factory.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
String jpql = "from Customer";
Query query = em.createQuery(jpql);
query.setFirstResult(0); //起始索引
query.setMaxResults(2); //每頁顯示條數
List list = query.getResultList(); //得到集合返回類型
for (Object object : list) {
System.out.println(object);
}
tx.commit();
em.close();
factory.close();
}
5.4 排序查詢
@Test
public void test() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
EntityManager em = factory.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
String jpql = "from Customer order by custId desc";
Query query = em.createQuery(jpql);
List list = query.getResultList(); //得到集合返回類型
for (Object object : list) {
System.out.println(object);
}
tx.commit();
em.close();
factory.close();
}
5.5 統計查詢
@Test
public void test() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
EntityManager em = factory.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
String jpql = "select count(custId) from Customer";
Query query = em.createQuery(jpql);
Object count = query.getSingleResult(); //得到唯一的結果集對象
System.out.println(count);
tx.commit();
em.close();
factory.close();
}