Hibernate - 查詢語言



Hibernate 查詢語言 (HQL) 是一種面向物件的查詢語言,類似於 SQL,但它不是操作表和列,而是操作持久化物件及其屬性。HQL 查詢由 Hibernate 轉換為傳統的 SQL 查詢,後者再對資料庫執行操作。

雖然您可以使用原生 SQL 直接在 Hibernate 中使用 SQL 語句,但我建議儘可能使用 HQL,以避免資料庫移植方面的麻煩,並利用 Hibernate 的 SQL 生成和快取策略。

SELECT、FROM 和 WHERE 等關鍵字不區分大小寫,但表和列名在 HQL 中區分大小寫。

FROM 子句

如果您想將完整的持久化物件載入到記憶體中,可以使用 FROM 子句。以下是使用 FROM 子句的簡單語法:

String hql = "FROM Employee";
Query query = session.createQuery(hql);
List results = query.list();

如果您需要在 HQL 中完全限定類名,只需指定包名和類名,如下所示:

String hql = "FROM com.hibernatebook.criteria.Employee";
Query query = session.createQuery(hql);
List results = query.list();

AS 子句

AS 子句可用於為 HQL 查詢中的類分配別名,尤其是在查詢很長的情況下。例如,我們之前的簡單示例如下所示:

String hql = "FROM Employee AS E";
Query query = session.createQuery(hql);
List results = query.list();

AS 關鍵字是可選的,您也可以在類名後直接指定別名,如下所示:

String hql = "FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

SELECT 子句

SELECT 子句比 FROM 子句提供對結果集的更多控制。如果您想獲取物件的某些屬性而不是整個物件,請使用 SELECT 子句。以下是使用 SELECT 子句僅獲取 Employee 物件的 first_name 欄位的簡單語法:

String hql = "SELECT E.firstName FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

這裡需要注意的是,Employee.firstName 是 Employee 物件的屬性,而不是 EMPLOYEE 表的欄位。

WHERE 子句

如果您想縮小從儲存中返回的特定物件範圍,可以使用 WHERE 子句。以下是使用 WHERE 子句的簡單語法:

String hql = "FROM Employee E WHERE E.id = 10";
Query query = session.createQuery(hql);
List results = query.list();

ORDER BY 子句

要對 HQL 查詢的結果進行排序,需要使用 ORDER BY 子句。您可以按結果集中的物件的任何屬性進行排序,升序 (ASC) 或降序 (DESC)。以下是使用 ORDER BY 子句的簡單語法:

String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC";
Query query = session.createQuery(hql);
List results = query.list();

如果您想按多個屬性排序,只需將其他屬性新增到 ORDER BY 子句的末尾,並用逗號分隔,如下所示:

String hql = "FROM Employee E WHERE E.id > 10 " +
             "ORDER BY E.firstName DESC, E.salary DESC ";
Query query = session.createQuery(hql);
List results = query.list();

GROUP BY 子句

此子句允許 Hibernate 從資料庫提取資訊,並根據屬性值對其進行分組,通常使用結果包含聚合值。以下是使用 GROUP BY 子句的簡單語法:

String hql = "SELECT SUM(E.salary), E.firtName FROM Employee E " +
             "GROUP BY E.firstName";
Query query = session.createQuery(hql);
List results = query.list();

使用命名引數

Hibernate 在其 HQL 查詢中支援命名引數。這使得編寫接受使用者輸入的 HQL 查詢變得容易,並且您不必防禦 SQL 注入攻擊。以下是使用命名引數的簡單語法:

String hql = "FROM Employee E WHERE E.id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id",10);
List results = query.list();

UPDATE 子句

批次更新是 Hibernate 3 中 HQL 的新增功能,刪除操作在 Hibernate 3 中的工作方式與 Hibernate 2 中有所不同。Query 介面現在包含一個名為 executeUpdate() 的方法,用於執行 HQL UPDATE 或 DELETE 語句。

UPDATE 子句可用於更新一個或多個物件的屬性。以下是使用 UPDATE 子句的簡單語法:

String hql = "UPDATE Employee set salary = :salary "  + 
             "WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("salary", 1000);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

DELETE 子句

DELETE 子句可用於刪除一個或多個物件。以下是使用 DELETE 子句的簡單語法:

String hql = "DELETE FROM Employee "  + 
             "WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

INSERT 子句

HQL 只支援INSERT INTO 子句,用於將記錄從一個物件插入到另一個物件。以下是使用 INSERT INTO 子句的簡單語法:

String hql = "INSERT INTO Employee(firstName, lastName, salary)"  + 
             "SELECT firstName, lastName, salary FROM old_employee";
Query query = session.createQuery(hql);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

聚合方法

HQL 支援一系列聚合方法,類似於 SQL。它們在 HQL 中的工作方式與在 SQL 中相同,以下是可用函式的列表:

序號 函式及說明
1

avg(屬性名)

屬性值的平均值

2

count(屬性名或 *)

屬性在結果中出現的次數

3

max(屬性名)

屬性值的最大值

4

min(屬性名)

屬性值的最小值

5

sum(屬性名)

屬性值的總和

distinct 關鍵字只計算行集中的唯一值。以下查詢將只返回唯一計數:

String hql = "SELECT count(distinct E.firstName) FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

使用 Query 進行分頁

Query 介面有兩種分頁方法。

序號 方法及說明
1

Query setFirstResult(int startPosition)

此方法接受一個整數,表示結果集中的第一行,從第 0 行開始。

2

Query setMaxResults(int maxResult)

此方法告訴 Hibernate 檢索固定數量的 maxResults 物件。

結合使用以上兩種方法,我們可以在 Web 或 Swing 應用程式中構建分頁元件。以下是一個示例,您可以將其擴充套件為一次獲取 10 行資料:

String hql = "FROM Employee";
Query query = session.createQuery(hql);
query.setFirstResult(1);
query.setMaxResults(10);
List results = query.list();
廣告