首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2EE

深度解析 JPA 2.0 Criteria API (一):從 JPQL 痛點到類型安全查詢新範式

     編輯:J2EE

JPA 1.0 引入 JPQL 大幅簡化持久化查詢,但其字串本質帶來三大痛點:編譯期無法檢查語法/語義、執行期才暴露拼寫錯誤、結果列表無泛型需強制轉型。JPA 2.0 (JSR 317) 推出的 Criteria API 徹底改寫查詢範式:以 泛型表達式樹 取代字串,實現編譯期類型安全與動態可編程構建雙重突破。本文為系列首篇,奠定核心概念與基礎用法。

JPQL 的致命缺陷:字串查詢的「盲區」

String jpql = "select p from Person where p.age > 20"; // 缺少別名 p
Query query = em.createQuery(jpql); // 編譯通過,執行拋異常

編譯器將 JPQL 視為普通字串,無法感知實體結構、屬性類型、關聯路徑。任何拼寫錯誤、類型不匹配、關聯斷裂,皆需部署至伺服器執行才能發現,嚴重拖慢開發迴路。

Criteria API 核心組件速覽

介面/類角色關鍵泛型參數
QueryBuilder查詢與表達式工廠—
CriteriaQuery<T>查詢定義根節點,封裝 FROM/WHERE/SELECT/OrderByT = 結果類型
Root<T>查詢根(FROM 子句),特殊的 PathT = 實體類型
Path<T>從 Root 導航到的持久屬性/關聯路徑T = 屬性類型
Predicate布爾表達式(WHERE 子句),繼承 Expression<Boolean>—
TypedQuery<T>可執行查詢,擴展 Query,getResultList() 回傳 List<T>T = 結果類型

基礎查詢構建五步曲

EntityManager em = ...;
QueryBuilder qb = em.getQueryBuilder();
CriteriaQuery<Person> c = qb.createQuery(Person.class);        // 1. 指定結果類型
Root<Person> p = c.from(Person.class);                          // 2. 定義查詢根
Predicate cond = qb.gt(p.get(Person_.age), 20);                 // 3. 構建型安全謂詞
c.where(cond);                                                  // 4. 設定 WHERE
TypedQuery<Person> q = em.createQuery(c);                       // 5. 獲得型安全可執行查詢
List<Person> result = q.getResultList();                        // 直接得到 List<Person>

關鍵亮點:

  • qb.gt(Expression<? extends Number>, Number) 簽名強制雙方為數值型,編譯期阻擋字串比較。
  • Person_.age 來自靜態元模型(下篇詳述),提供屬性的編譯期句柄。
  • TypedQuery 保留泛型資訊,消除遍歷結果時的強轉與 ClassCastException 風險。

查詢表達式樹:結構化的 SQL/AST

CriteriaQuery 內部為表達式節點樹,對應傳統子句:

  • from() → Root(FROM)
  • where() → Predicate(WHERE)
  • select() / multiselect() → Selection(SELECT)
  • orderBy() → Order(ORDER BY)
  • groupBy() / having() → 分組與過濾

所有節點皆為泛型 Expression<T> 子型別,構成強類型 AST,可序列化、可遍歷、可轉換(如生成 SQL、NoSQL 查詢、GraphQL 解析器)。

下一篇預告

下一篇將深入 靜態元模型(Canonical Metamodel) 生成機制、Metamodel API 型別體系、SingularAttribute/PluralAttribute 區分、運行時 Metamodel 容器與持久化單元作用域對應,並示範函數表達式、複合謂詞、連接、參數化與多樣化結果投影實戰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved