Hibernate - 查询语言


Hibernate 查询语言 (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.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();

选择子句

与 from 子句相比, SELECT子句对结果集提供更多控制。如果要获取对象的少数属性而不是完整的对象,请使用 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();

更新条款

批量更新是 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 子句的简单语法 -

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

插入子句

仅当记录可以从一个对象插入到另一对象时,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

平均值(属性名称)

财产的平均价值

2

计数(属性名称或 *)

属性在结果中出现的次数

3

最大值(属性名称)

属性值的最大值

4

分钟(属性名称)

属性值的最小值

5

总和(属性名称)

财产价值总和

unique关键字仅计算行集中的唯一值。以下查询将仅返回唯一计数 -

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

使用查询分页

Query 接口有两种方法用于分页。

先生。 方法及说明
1

查询 setFirstResult(int startPosition)

此方法采用一个整数,表示结果集中的第一行,从第 0 行开始。

2

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