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

Hibernate 核心查詢方式:HQL 與 QBC 詳解

     編輯:Java 綜合教學

一、HQL (Hibernate Query Language) 查詢

以雙向一對多關聯的 Department 與 Employee 為例,展示常用 HQL 技巧。

1. 動態參數綁定與條件查詢

@Test
public void testHql() {
    Department dept = new Department(); dept.setDeptId(7);
    List<Employee> list = session.createQuery(
        "FROM Employee e WHERE e.empName LIKE ? AND e.empId > ? AND e.dept = ? ORDER BY e.empId DESC")
        .setString(0, "%b%").setInteger(1, 3).setEntity(2, dept).list();
    // 輸出結果...
}

說明:支援位置參數(從 0 起)、鏈式呼叫、setEntity 僅需 ID、ORDER BY 排序。

2. 命名參數查詢

@Test
public void testHqlNamed() {
    List<Employee> list = session.createQuery(
        "FROM Employee e WHERE e.empName LIKE :name AND e.empId > :id AND e.dept = ?")
        .setString("name", "%a%").setInteger("id", 1).list();
}

3. 部分屬性查詢(投影)

  • 返回 Object[]:SELECT empName, empId FROM Employee ...
  • 返回實體:SELECT NEW Employee(empId, empName) FROM Employee ... 需實體提供對應建構子。

4. 分頁查詢

session.createQuery("FROM Employee")
       .setFirstResult((pageNo - 1) * pageSize)
       .setMaxResults(pageSize).list();

5. 命名查詢(在 .hbm.xml 中定義)

session.getNamedQuery("findAllEmployees")
       .setFirstResult(...).setMaxResults(...).list();

6. 聚集函數與分組

SELECT dept.deptName, MIN(salary), MAX(salary)
FROM Employee GROUP BY dept HAVING MIN(salary) > :salary

7. 迫切左外連接 vs 普通左外連接

  • LEFT JOIN FETCH:一次查詢關聯集合並初始化,忽略映射檔策略,返回實體列表(可能重複,可用 DISTINCT 或 Set 去重)。
  • LEFT JOIN:返回 Object[],關聯集合初始化時機遵循映射檔策略(預設 lazy)。

8. 小結

  • HQL 未指定策略時使用映射檔設定。
  • HQL 忽略映射檔中的 fetch="join",必須在 HQL 顯式指定 FETCH。

二、QBC (Query By Criteria) 查詢

完全面向物件風格,適合動態組裝條件。

1. 條件構建

Criteria criteria = session.createCriteria(Employee.class);
criteria.add(Restrictions.like("empName", "a", MatchMode.ANYWHERE));
criteria.add(Restrictions.gt("salary", 1000F));
criteria.addOrder(Order.desc("salary"));

2. AND / OR 組合

Conjunction and = Restrictions.conjunction();
and.add(Restrictions.like("empName", "a", MatchMode.ANYWHERE));
and.add(Restrictions.eq("dept", dept));

Disjunction or = Restrictions.disjunction();
or.add(Restrictions.gt("salary", 1000F));
or.add(Restrictions.lt("salary", 20000F));

criteria.add(and).add(or);

3. 分頁、聚集、單一結果

criteria.setFirstResult(...).setMaxResults(...).list();
criteria.setProjection(Projections.max("salary"));
String max = criteria.uniqueResult().toString();

三、本地 SQL 查詢

session.createSQLQuery("SELECT emp_name FROM employee WHERE emp_id = ?")
       .setEntity(0, employee).uniqueResult();

四、HQL 更新/刪除

session.createQuery("DELETE FROM Employee WHERE empId = ?")
       .setInteger(0, 13).executeUpdate();

五、總結

  • 三種查詢入口:createQuery、createCriteria、createSQLQuery。
  • QBC 提供更徹底的面向物件風格。
  • 重點掌握「迫切左外連接」在 HQL 與映射檔中的行為差異。
  • 本地 SQL 作為 HQL 補充。

ER圖

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