Hibernate 简明教程

Hibernate - Query Language

Hibernate 查询语言 (HQL) 是一种面向对象查询语言,类似于 SQL,但 HQL 不操作表和列,而是处理持久对象及其属性。HQL 查询由 Hibernate 转换为常规 SQL 查询,进而对数据库执行操作。

虽然可以使用本机 SQL 直接在 Hibernate 中使用 SQL 语句,但我建议尽可能使用 HQL 来避免数据库移植麻烦,并利用 Hibernate 的 SQL 生成和缓存策略。

SELECT、FROM 和 WHERE 等关键字不区分大小写,但 HQL 中的属性(如表和列名)区分大小写。

FROM Clause

如果要将一个完整的持久对象加载到内存中,可以使用 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 Clause

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 Clause

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 Clause

如果想要缩小从存储中返回的特定对象范围,可以使用 WHERE 子句。以下是使用 WHERE 子句的简单语法:

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

ORDER BY Clause

要对 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 Clause

此子句允许 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();

Using Named Parameters

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 Clause

批量更新在 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 Clause

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 Clause

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);

Aggregate Methods

HQL 支持一系列聚合方法,与 SQL 类似。它们在 HQL 中的工作方式与在 SQL 中相同,以下是可用函数的列表:

Sr.No.

Functions & Description

1

avg(property name) 属性值的平均值

2

count(property name or *) 某个属性在结果中出现的次数

3

max(property name) 属性值的最大值

4

min(property name) 属性值的最小值

5

sum(property name) 属性值的总和

distinct 关键词仅对行集中唯一的值进行计数。以下查询将仅返回唯一计数 −

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

Pagination using Query

查询接口有两个方法用于分页。

Sr.No.

Method & Description

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();