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

Hibernate HQL 查詢語言全攻略:從入門到進階實戰

     編輯:Java 綜合教學

Hibernate HQL 查詢語言全攻略:從入門到進階實戰

HQL (Hibernate Query Language) 是面向對象的查詢語言,操作的是持久化類及其屬性,而非數據庫表和列。本文系統梳理 HQL 核心語法、聚合分組、參數綁定、子查詢等實戰技巧。

基本查詢

// 查詢所有學生對象
List<Student> list = session.createQuery("from Student").list();

// 唯一結果查詢(高效,避免列表開銷)
Student s = (Student) session.createQuery("from Student where sid='20050003'").uniqueResult();

投影查詢與去重

// 查詢指定屬性,返回 Object[] 數組
List<Object[]> list = session.createQuery("select distinct sage, ssex from Student").list();
for (Object[] objs : list) {
    System.out.println(objs[0] + " " + objs[1]);
}

條件查詢

// Between
List<Object[]> list = session.createQuery("select sage, ssex, sname from Student where sage between 20 and 22").list();

// IN / NOT IN
List<Student> list = session.createQuery("from Student where sdept in ('計算機系','外語系')").list();

分組聚合與 HAVING

// 各系平均年齡
List<Object[]> list = session.createQuery("select avg(sage), sdept from Student group by sdept").list();

// 人數大於 3 的系
List<Object[]> list = session.createQuery("select count(*) as c1, sdept from Student group by sdept having count(*) > 3").list();

// 計算機系人數(單列聚合返回 List<Object> 而非 Object[])
List<Object> list = session.createQuery("select count(*) from Student where sdept='計算機系'").list();

參數綁定(防注入、預編譯、性能)

命名參數(推薦,可讀性強)

Query q = session.createQuery("from Student where sdept=:dept and sage > :age");
List<Student> list = q.setString("dept", "計算機系").setInteger("age", 20).list();

位置參數(JDBC 風格)

Query q = session.createQuery("from Student where sdept=? and sage > ?");
List<Student> list = q.setString(0, "計算機系").setInteger(1, 20).list();

分開綁定

Query query = session.createQuery("from Student where sdept=? and sage > ?");
query.setString(0, "計算機系");
query.setInteger(1, 20);
List<Student> list = query.list();

面試高頻題:不使用參數綁定如何防 SQL 注入?

思路:通過用戶名查詢數據庫中存儲的密碼哈希,再與用戶輸入的密碼哈希比對,而非拼接 SQL。但參數綁定是標準、最安全、最高效的方案,無需重複造輪子。

進階:子查詢與連接查詢

// 子查詢:查詢選修 11 號課程的最高/最低分
List<Object[]> list = session.createQuery(
    "select 11, max(grade), min(grade) from Studcourse where course.cid = 11").list();

// 隱式內連接(導航屬性)
List<Object[]> list = session.createQuery(
    "select count(*), student.sdept from Studcourse where grade < 60 group by student.sdept").list();

HQL vs SQL 關鍵差異

特性HQLSQL
面向類/屬性表/列
大小寫敏感類名/屬性名敏感,關鍵字不敏感視數據庫而定
多態查詢支持 from Animal 查詢所有子類不支持
分頁query.setFirstResult().setMaxResults()方言相關 (LIMIT/ROWNUM/OFFSET)
返回類型實體、Object[]、List、Map、標量ResultSet

最佳實踐

  1. 優先使用命名參數,業務含義清晰。
  2. 大結果集分頁查詢,避免 OOM。
  3. 僅查詢所需屬性(投影),減少數據傳輸與實體化開銷。
  4. 利用二級緩存、查詢緩存優化熱點數據。
  5. 複雜報表統計優先考慮原生 SQL 或視圖,HQL 表達力有限。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved