查询语言(Query Language)
Hibernate查询语言(HQL)是一种面向对象的查询语言,类似于SQL,但HQL不是对表和列进行操作,而是使用持久对象及其属性。 HQL查询由Hibernate转换为传统的SQL查询,后者依次对数据库执行操作。
虽然你可以使用Native SQL直接使用Hibernate的SQL语句,但我建议尽可能使用HQL来避免数据库可移植性的麻烦,并利用Hibernate的SQL生成和缓存策略。
SELECT,FROM和WHERE等关键字不区分大小写,但是表和列名称等属性在HQL中区分大小写。
来自条款
如果要将完整的持久对象加载到内存中,则将使用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子句提供对结果集的更多控制,然后是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子句的简单语法 -
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);
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中的工作方式相同,以下是可用功能的列表 -
Sr.No. | 功能和描述 |
---|---|
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进行分页
分页的Query接口有两种方法。
Sr.No. | 方法和描述 |
---|---|
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();