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

深度解析 JPA 2.0 Criteria API (三):動態弱類型、資料庫函數擴展、可編輯查詢與 QBE

     編輯:J2EE

本系列最終篇聚焦 Criteria API 的動態可編程特性:弱類型 API 支援純運行時決定實體、function() 呼叫資料庫專屬函數、查詢物件可編輯實現「結果中搜尋」、以及 Query-by-Example(QBE)模板查詢。這些能力讓 Criteria API 超越靜態 JPQL,成為構建靈活查詢引擎的核心基建。

弱類型 API:犧牲編譯檢查換取極致動態

當實體類型僅在運行時已知(如通用報表引擎),可用字串屬性名替代靜態元模型:

Class<Account> cls = Class.forName("domain.Account");
EntityType<Account> entity = em.getMetamodel().entity(cls);
CriteriaQuery<Account> c = cb.createQuery(cls);
Root<Account> account = c.from(entity);
Path<Integer> balance = account.<Integer>get("balance"); // 需顯式泛型轉型
c.where(cb.and(cb.greaterThan(balance, 100), cb.lessThan(balance, 200)));

編譯器會警告 unchecked cast,可用參數化方法調用 account.<Integer>get("balance") 抑制警告。此模式失去編譯期類型安全,換取運行時結構自由度。

可擴展資料庫表達式:function() 突破 JPQL 語法侷限

JPQL 僅支援標準函數,Criteria API 透過 cb.function(String name, Class<T> type, Expression<?>... args) 直接映射資料庫原生函數:

Expression<String> currentUser = cb.function("CURRENT_USER", String.class, (Expression<?>[])null);
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Customer> c = q.from(Customer.class);
q.multiselect(currentUser, c.get(Customer_.balanceOwed));

等效 JPQL 無法表達,動態 API 不受預定義語法束縛,支援任意資料庫擴展函數(Oracle DECODE、PostgreSQL jsonb_extract 等)。

可編輯查詢:構建「結果中搜尋」交互體驗

CriteriaQuery 的 setter(select()、where()、orderBy())可替換子句,getter(getOrderList() 等)回傳快照列表(非活動視圖)。最佳實踐:複製列表、修改、再 set 回去:

List<Order> orders = c.getOrderList();
List<Order> newOrders = new ArrayList<>(orders);
newOrders.add(cb.desc(p.get(Person_.zipcode)));
c.orderBy(newOrders); // 追加排序條件
List<Person> result2 = em.createQuery(c).getResultList();

此機制天然支援分步篩選、動態排序、分頁參數調整等交互式查詢場景。

Query-by-Example (QBE):以模板實例自動生成謂詞

QBE 由 IBM Research 1970 年代提出,用非 null/非預設值屬性自動組合聯合謂詞。JPA 2.0 標準未納入,但 OpenJPA 透過擴展介面支援:

CriteriaQuery<Employee> q = cb.createQuery(Employee.class);
Employee example = new Employee();
example.setSalary(10000);
example.setRating(1);
q.where(cb.qbe(q.from(Employee.class), example));
// 自動生成:salary = 10000 AND rating = 1

可進一步指定排除屬性、字串比較模式(精確/模糊/前綴),極適合「高級搜尋表單」後端自動構建。

結語:Criteria API 的雙重價值

  1. 靜態類型安全:靜態元模型 + 泛型表達式樹,將查詢錯誤左移至編譯期。
  2. 動態可編程:表達式樹可組合、可擴展、可編輯、可序列化,支援通用查詢引擎、報表設計器、動態儀表板等進階應用。

JPA 2.0 Criteria API 不只是 JPQL 的類型安全替代品,更是「以程式碼構建查詢」的標準化 AST(抽象語法樹)API。掌握其靜態與動態雙重面向,能讓持久層從「寫 SQL 字串」進化為「構建查詢物件」,顯著提升可維護性與擴展性。

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