Hibernate 查询语言
Hibernate Query Language (HQL) 是一种面向对象的查询语言,类似于 SQL,但 HQL 不是对表和列进行操作,而是使用持久对象及其属性。 HQL 查询被 Hibernate 翻译成常规的 SQL 查询,后者反过来对数据库执行操作。
虽然我们可以使用 Native 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.jiyik.domain.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 子句
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(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();
使用查询进行分页
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();