JPA(七)查詢總結
一、根據id查詢
顧名思義:即根據主鍵查詢一個實體。在 JPA 中提供了兩個方法。分別是:
find(Class entityClass,Object id);
getReference(Class entityClass,Object id);
他們的區別是:
查詢的時機不一樣:
find 的方法是立即載入,只要一呼叫方法就馬上發起查詢。
getReference 方法是延遲載入,只有真正用到資料時才發起查 詢。(按需載入)
返回的結果不一樣:
find 方法返回的是實體類物件。
getReference 方法返回的是實體類的代理物件。
示例
//查詢一個
//立即載入
@Test
public void testFindOne() {
EntityManager em = JPAUtil.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Customer c = em.find(Customer.class, 1);
System.out.println(c);
tx.commit();
em.close();
}
//查詢一個
//懶載入(延遲載入)
@Test
public void testFindOne2() {
EntityManager em = JPAUtil.createEntityManager ();
EntityTransaction tx = em.getTransaction();
tx.begin();
Customer c = em.getReference(Customer.class, 1);
System.out.println(c.toString());
tx.commit();
em.close();
}
二、物件導航查詢
此種查詢方式,是根據已知實體,呼叫該實體中的 getXXX 方法獲取到關聯物件的資訊。
例如:
Customer 物件中有一個 LinkMan 的集合屬性,並生成了 get 和 set 方法。
我們就可以通過 getLinkMans()得到該客戶下的所有聯絡人資訊。
要求:
兩個實體必須有關聯關係,才能使用此種查詢方式。
示例:
/**
* 根據客戶導航查詢聯絡人
*/
@Test
public void test() {
// 定義物件
EntityManager em = null;
EntityTransaction tx = null;
try {
// 獲取實體管理物件
em = JpaUtil.getEntityManager();
// 獲取事務物件
tx = em.getTransaction();
// 開啟事務
tx.begin();
// 執行操作
Customer c1 = em.find(Customer.class, 26L);
System.out.println(c1); // 輸出查詢物件
Set<LinkMan> linkMans = c1.getLinkMans();
for (LinkMan linkMan : linkMans) {
System.out.println(linkMan);
}
// 提交事務
tx.commit();
} catch (Exception e) {
// 回滾事務
tx.rollback();
e.printStackTrace();
} finally {
// 釋放資源
em.close();
}
}
/**
* 根據聯絡人導航查詢客戶
*/
@Test
public void test2() {
// 定義物件
EntityManager em = null;
EntityTransaction tx = null;
try {
// 獲取實體管理物件
em = JpaUtil.getEntityManager();
// 獲取事務物件
tx = em.getTransaction();
// 開啟事務
tx.begin();
// 執行操作
LinkMan linkMan = em.find(LinkMan.class, 35L);
System.out.println(linkMan); // 輸出查詢物件
Customer customer = linkMan.getCustomer();
System.out.println(customer); //輸入導航查詢結果
// 提交事務
tx.commit();
} catch (Exception e) {
// 回滾事務
tx.rollback();
e.printStackTrace();
} finally {
// 釋放資源
em.close();
}
}
三、JPQL查詢
此種方式是使用 JPQL 語句查詢。全稱是 Java Persistence Query Language。JPQL 語句是 JPA 中定義的一種查詢語言。此種語言的用意是讓開發者忽略資料庫表和表中的欄位,而關注實體類及實體類中的屬性。更加契合操作實體類就相當於操作資料庫表的 ORM 思想。但是又不完全脫離 SQL 語句,例如:
排序,仍然使用 order 關鍵字。
聚合函式:在 JPQL 中也可以是使用。
它的寫法是:
把查詢的表名換成實體類名稱,把表中的欄位名換成實體類的屬性名稱。
注意:
此處我們必須明確,實體類屬性名稱指的是 get/set 方法後面的部分,且首字母改小寫。而非私
有類成員變數。只不過我們的 get/set 方法都是通過工具生成的,所以可以直接寫私有成員變數名稱。
/**
* 根據id查詢
*/
@Test
public void test() {
// 定義物件
EntityManager em = null;
EntityTransaction tx = null;
try {
// 獲取實體管理物件
em = JpaUtil.getEntityManager();
// 獲取事務物件
tx = em.getTransaction();
// 開啟事務
tx.begin();
//JPQL建立查詢語句
//Query query = em.createQuery("select c from Customer c where c.id = ?");
//也可以勝率select c
Query query = em.createQuery(" from Customer where custId = ?");
query.setParameter(1, 26L);
// 執行操作
List list = query.getResultList();
for (Object object : list) {
System.out.println(object);
}
// 提交事務
tx.commit();
} catch (Exception e) {
// 回滾事務
tx.rollback();
e.printStackTrace();
} finally {
// 釋放資源
em.close();
}
}
四、SQL查詢
此種方式是使用原生SQL語句查詢資料庫。採用此種方式查詢,我們可以在資料庫視覺化編譯器中先把語句寫好,然後粘到程式碼中。
注意:
一般採用 ORM 框架作為持久層解決方案時,很少使用原生 SQL 語句。(特定情況除外:例如統計分析的語句,一般用於複雜查詢)
/**
* 根據id查詢
*/
@Test
public void test() {
// 定義物件
EntityManager em = null;
EntityTransaction tx = null;
try {
// 獲取實體管理物件
em = JpaUtil.getEntityManager();
// 獲取事務物件
tx = em.getTransaction();
// 開啟事務
tx.begin();
Query query = em.createNativeQuery(
"select * from cst_customer", Customer.class);
// 執行操作
List<Customer> list = query.getResultList();
for (Customer cust : list) {
System.out.println(cust);
}
// 提交事務
tx.commit();
} catch (Exception e) {
// 回滾事務
tx.rollback();
e.printStackTrace();
} finally {
// 釋放資源
em.close();
}
}
五、QBC查詢
QBC 全稱是 Query By Criteria。此種方式是一種更加面向物件的查詢方式。並且可擴充套件條件查詢 API,通過它完全不需要考慮資料庫底層如何實現,以及 SQL 語句如何編寫。
細節:
JPQL 能查的,QBC 都能查,反之亦然。
/**
*
* 5、查詢所有客戶
*/
@Test
public void findAll() {
EntityManager em = null;
EntityTransaction tx = null;
// 1.獲取 JPA 的操作資料庫物件
em = JpaUtil.getEntityManager();
// 3.開啟事務
tx = em.getTransaction();
tx.begin();
// 4.建立 CriteriaBuilder(條件構建)物件,該物件中定義著查詢條件涉及的方法,通過該物件設定查詢條件
CriteriaBuilder cb = em.getCriteriaBuilder();
// 5.獲取 QBC 的查詢的物件 CriteriaQuery.
// 它可以加一些 SQL 的子句例如:where/group by/order by/having 等等。
CriteriaQuery<Customer> cq = cb.createQuery(Customer.class);
// 6.獲取實體類物件的封裝物件,有此物件之後,所有實體類都可以看成此型別
Root<Customer> root = cq.from(Customer.class);
// 7.建立條件物件
Predicate p1 = cb.like(root.get("custName"), "%天%");
Predicate p2 = cb.equal(root.get("custLevel"), "VIP 客戶");
Predicate p3 = cb.between(root.get("custId"), 10, 20);
// 8.構建排序條件,並獲取構建排序後的QBC 的查詢物件
Order o = cb.desc(root.get("custId"));
CriteriaQuery<Customer> cq1 = cq.orderBy(o);
// 9.給查詢物件設定查詢條件
cq1.where(p1, p2, p3);
TypedQuery<Customer> createQuery = em.createQuery(cq1);
// 10.執行查詢,獲取結果
List list = createQuery.getResultList(); // 得到集合返回型別
for (Object object : list) {
System.out.println(object);
}
// 提交事物
tx.commit();
// 釋放資源
em.close();
}