Hibernate 简明教程
Hibernate - Query Language
Hibernate 查询语言 (HQL) 是一种面向对象查询语言,类似于 SQL,但 HQL 不操作表和列,而是处理持久对象及其属性。HQL 查询由 Hibernate 转换为常规 SQL 查询,进而对数据库执行操作。
Hibernate Query Language (HQL) is an object-oriented query language, similar to SQL, but instead of operating on tables and columns, HQL works with persistent objects and their properties. HQL queries are translated by Hibernate into conventional SQL queries, which in turns perform action on database.
虽然可以使用本机 SQL 直接在 Hibernate 中使用 SQL 语句,但我建议尽可能使用 HQL 来避免数据库移植麻烦,并利用 Hibernate 的 SQL 生成和缓存策略。
Although you can use SQL statements directly with Hibernate using Native SQL, but I would recommend to use HQL whenever possible to avoid database portability hassles, and to take advantage of Hibernate’s SQL generation and caching strategies.
SELECT、FROM 和 WHERE 等关键字不区分大小写,但 HQL 中的属性(如表和列名)区分大小写。
Keywords like SELECT, FROM, and WHERE, etc., are not case sensitive, but properties like table and column names are case sensitive in HQL.
FROM Clause
如果要将一个完整的持久对象加载到内存中,可以使用 FROM 子句。以下是使用 FROM 子句的简单语法:
You will use FROM clause if you want to load a complete persistent objects into memory. Following is the simple syntax of using FROM clause −
String hql = "FROM Employee";
Query query = session.createQuery(hql);
List results = query.list();
如果需要在 HQL 中完全限定一个类名,只需按如下所示指定包名和类名:
If you need to fully qualify a class name in HQL, just specify the package and class name as follows −
String hql = "FROM com.hibernatebook.criteria.Employee";
Query query = session.createQuery(hql);
List results = query.list();
AS Clause
AS 子句可用于为 HQL 查询中的类分配别名,特别是在有长查询时。例如,我们之前的简单示例将如下所示:
The AS clause can be used to assign aliases to the classes in your HQL queries, especially when you have the long queries. For instance, our previous simple example would be the following −
String hql = "FROM Employee AS E";
Query query = session.createQuery(hql);
List results = query.list();
AS 关键字是可选的,还可以按如下所示直接在类名后面指定别名:
The AS keyword is optional and you can also specify the alias directly after the class name, as follows −
String hql = "FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();
SELECT Clause
SELECT 子句比 from 子句可对结果集提供更多控制。如果想要获取对象的部分属性而不是整个对象,可以使用 SELECT 子句。以下是使用 SELECT 子句获取 Employee 对象的 first_name 字段的简单语法:
The SELECT clause provides more control over the result set then the from clause. If you want to obtain few properties of objects instead of the complete object, use the SELECT clause. Following is the simple syntax of using SELECT clause to get just first_name field of the Employee object −
String hql = "SELECT E.firstName FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();
值得注意的是, Employee.firstName 是 Employee 对象的属性,而不是 EMPLOYEE 表的字段。
It is notable here that Employee.firstName is a property of Employee object rather than a field of the EMPLOYEE table.
WHERE Clause
如果想要缩小从存储中返回的特定对象范围,可以使用 WHERE 子句。以下是使用 WHERE 子句的简单语法:
If you want to narrow the specific objects that are returned from storage, you use the WHERE clause. Following is the simple syntax of using WHERE clause −
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 子句的简单语法:
To sort your HQL query’s results, you will need to use the ORDER BY clause. You can order the results by any property on the objects in the result set either ascending (ASC) or descending (DESC). Following is the simple syntax of using ORDER BY clause −
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 子句的末尾:
If you wanted to sort by more than one property, you would just add the additional properties to the end of the order by clause, separated by commas as follows −
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 子句的简单语法:
This clause lets Hibernate pull information from the database and group it based on a value of an attribute and, typically, use the result to include an aggregate value. Following is the simple syntax of using GROUP BY clause −
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 注入攻击。以下是使用命名参数的简单语法:
Hibernate supports named parameters in its HQL queries. This makes writing HQL queries that accept input from the user easy and you do not have to defend against SQL injection attacks. Following is the simple syntax of using named parameters −
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 语句。
Bulk updates are new to HQL with Hibernate 3, and delete work differently in Hibernate 3 than they did in Hibernate 2. The Query interface now contains a method called executeUpdate() for executing HQL UPDATE or DELETE statements.
UPDATE 子句可用于更新一个或多个对象的多个属性。以下是使用 UPDATE 子句的简单语法:
The UPDATE clause can be used to update one or more properties of an one or more objects. Following is the simple syntax of using UPDATE clause −
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 子句的简单语法:
The DELETE clause can be used to delete one or more objects. Following is the simple syntax of using DELETE clause −
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 子句的简单语法:
HQL supports INSERT INTO clause only where records can be inserted from one object to another object. Following is the simple syntax of using INSERT INTO clause −
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 中相同,以下是可用函数的列表:
HQL supports a range of aggregate methods, similar to SQL. They work the same way in HQL as in SQL and following is the list of the available functions −
Sr.No. |
Functions & Description |
1 |
avg(property name) The average of a property’s value |
2 |
count(property name or *) The number of times a property occurs in the results |
3 |
max(property name) The maximum value of the property values |
4 |
min(property name) The minimum value of the property values |
5 |
sum(property name) The sum total of the property values |
distinct 关键词仅对行集中唯一的值进行计数。以下查询将仅返回唯一计数 −
The distinct keyword only counts the unique values in the row set. The following query will return only unique count −
String hql = "SELECT count(distinct E.firstName) FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();
Pagination using Query
查询接口有两个方法用于分页。
There are two methods of the Query interface for pagination.
Sr.No. |
Method & Description |
1 |
Query setFirstResult(int startPosition) This method takes an integer that represents the first row in your result set, starting with row 0. |
2 |
Query setMaxResults(int maxResult) This method tells Hibernate to retrieve a fixed number maxResults of objects. |
将以上两个方法结合使用,我们可以在 Web 或 Swing 应用程序中构建一个分页组件。以下就是其示例,您可以对其进行扩展以一次获取 10 行 −
Using above two methods together, we can construct a paging component in our web or Swing application. Following is the example, which you can extend to fetch 10 rows at a time −
String hql = "FROM Employee";
Query query = session.createQuery(hql);
query.setFirstResult(1);
query.setMaxResults(10);
List results = query.list();