Hướng dẫn Hibernate Query Language (HQL) qua Ví Dụ
Link Source: Hướng dẫn Hibernate Query Language (HQL) qua Ví Dụ
Thể loại: Java, Lập trình
Tags: Hibernate Framework, Học hành, Lập trình
Hướng dẫn Hibernate Query Language (HQL) qua 14 ví dụ
Hibernate Query Language (HQL) Example
Hibernate ORM framework cung cấp ngôn ngữ truy vấn gọi là Hibernate Query Language viết tắt là HQL. Nó rất mạnh mẽ và linh hoạt và có các đặc điểm sau:
- Tương tự như SQL: Cú pháp của HQL rất giống với SQL chuẩn. Nếu bạn quen thuộc với SQL thì viết HQL sẽ khá dễ dàng: từ SELECT, FROM, ORDER BY đến các biểu thức số học và các hàm tổng hợp, vv
- Hoàn toàn hướng đối tượng: HQL không sử dụng tên thật của bảng và cột trong cơ sở dữ liệu. Nó sử dụng tên lớp và tên thuộc tính thay thế. HQL có thể hiểu được thừa kế, đa hình và liên kết.
- Không phân biệt chữ hoa chữ thường cho các từ khóa (keywords): Điều đó có nghĩa là SELECT, select, Select là như nhau.
- Phân biệt chữ hoa chữ thường cho các lớp và thuộc tính của Java: HQL xem xét các trường hợp nhạy cảm cho các lớp Java và các thuộc tính của chúng, nghĩa là Person và person là hai đối tượng khác nhau.
Trong bài này, mình sẽ Hướng dẫn Hibernate Query Language (HQL) qua 14 ví dụ để thực hiện các truy vấn cơ bản (CRUD) cũng như các ứng dụng phổ biến khác. Lược đồ sau minh hoạ mối quan hệ của các bảng được sử dụng trong các ví dụ của hướng dẫn này:
Và đây là các lớp model đã map với JPA annotations:
Category class:
package net.codejava.hibernate;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "CATEGORY")
public class Category
private long id;
private String name;
private Set<Product> products;
public Category()
public Category(String name)
this.name = name;
@Id
@Column(name = "CATEGORY_ID")
@GeneratedValue
public long getId()
return id;
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL)
public Set<Product> getProducts()
return products;
// other getters and setters
Product class:
package net.codejava.hibernate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "PRODUCT")
public class Product
private long id;
private String name;
private String description;
private float price;
private Category category;
public Product()
public Product(String name, String description, float price,
Category category)
this.name = name;
this.description = description;
this.price = price;
this.category = category;
@Id
@Column(name = "PRODUCT_ID")
@GeneratedValue
public long getId()
return id;
@ManyToOne
@JoinColumn(name = "CATEGORY_ID")
public Category getCategory()
return category;
// other getters and setters
Order class:
package net.codejava.hibernate;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name = "ORDERS")
public class Order
private int id;
private String customerName;
private Date purchaseDate;
private float amount;
private Product product;
@Id
@Column(name = "ORDER_ID")
@GeneratedValue
public int getId()
return id;
public void setId(int id)
this.id = id;
@Column(name = "CUSTOMER_NAME")
public String getCustomerName()
return customerName;
@Column(name = "PURCHASE_DATE")
@Temporal(TemporalType.DATE)
public Date getPurchaseDate()
return purchaseDate;
@ManyToOne
@JoinColumn(name = "PRODUCT_ID")
public Product getProduct()
return product;
// other getters and setters
Hibernate Query Language (HQL) Example
Các ví dụ sắp tới được cung cấp dựa trên giả định rằng SessionFactory Hibernate được mở ra và một giao dịch(Transaction) đã được bắt đầu. Bạn có thể tìm hiểu thêm về cách lấy SessionFactory và bắt đầu một giao dịch trong hướng dẫn: Xây dựng Hibernate SessionFactory từ Service Registry. (updating)
1. Cách thực thi(execute) HQL trong Hibernate
Thực thi câu lệnh hql qua các bước dưới đây:
- Viết câu lệnh HQL:
String hql = "Your Query Goes Here";
- Tạo câu truy vấn Query từ phiên làm việc Session:
Query query = session.createQuery(hql);
- Thực thi query có 2 dạng: là bạn muốn thực thi dạng xem danh sách listing hay thực thi dạng cập nhật:
- Listing query (SELECT):
List listResult = query.list();
- Update query (INSERT, UPDATE, DELETE):
int rowsAffected = query.executeUpdate();
- Listing query (SELECT):
- Kết quả trả về từ câu truy vấn: phụ thuộc vào dạng truy vấn mà Hibernate trả về các kiểu kết quả khác nhau. Ví dụ:
- Select query một đối tượng sẽ trả về một danh sách các đối tượng đó.
- Join query trả về danh sách mảng Objects mà các bảng được kết với nhau(xem mỗi bảng là 1 object). Điều này cũng áp dụng cho các truy vấn sử dụng các hàm tổng hợp (count, sum, avg, etc).
Bây giờ chúng ta cùng vào các ví dụ chi tiết của Hướng dẫn Hibernate Query Language (HQL) qua ví dụ !
2. Ví dụ List Query
Đoạn mã sau đây thực thi một truy vấn mà kết quả trả về là danh sách Category:
String hql = "from Category";
Query query = session.createQuery(hql);
List<Category> listCategories = query.list();
for (Category aCategory : listCategories)
System.out.println(aCategory.getName());
Lưu ý rằng trong Hibernate Query Language(HQL), chúng ta có thể bỏ qua từ khoá SELECT và chỉ sử dụng FROM thay thế.
3. Ví dụ Search Query
Các câu lệnh thực hiện truy vấn tìm kiếm tất cả các sản phẩm trong một danh mục có tên là ‘Computer’:
String hql = "from Product where category.name = 'Computer'";
Query query = session.createQuery(hql);
List<Product> listProducts = query.list();
for (Product aProduct : listProducts)
System.out.println(aProduct.getName());
Điều thú vị ở đây là Hibernate tự động tạo truy vấn JOIN giữa bảng Product và Category một cách lặng im. Như lúc đầu mình đã nói HQL hoàn toàn hướng đối tượng và nó thể hiện rõ ở đây. Vì vậy, chúng ta không phải sử dụng từ khóa JOIN ở câu này:
String hql = "from Product where category.name = 'Computer'";
4. Dùng tham số cho câu truy vấn (Named Parameters)
Bạn có thể dùng tham số cho câu truy vấn bằng cách sử dụng dấu hai chấm trước tên tham số, ví dụ :id cho biết một trình giữ chỗ cho một tham số có tên id. Ví dụ sau minh họa cách viết và thực hiện một truy vấn bằng cách sử dụng các tham số được đặt tên:
String hql = "from Product where description like :keyword";
String keyword = "New";
Query query = session.createQuery(hql);
query.setParameter("keyword", "%" + keyword + "%");
List<Product> listProducts = query.list();
for (Product aProduct : listProducts)
System.out.println(aProduct.getName());
Các câu lệnh Hibernate Query Language(HQL) ở trên cho kết quả là tất cả các sản phẩm có mô tả chứa từ khoá được chỉ định(dòng 1). Sau đó sử dụng phương thức setParameter (name, value)
để thiết lập giá trị thực cho tham số được đặt tên.(dòng 5)
Lưu ý rằng chúng ta muốn thực hiện một tìm kiếm LIKE để các dấu phần trăm phải được sử dụng bên ngoài chuỗi truy vấn, không giống như SQL truyền thống.
5. Ví dụ Insert – Select Query
HQL không hỗ trợ câu lệnh INSERT thông thường (bạn biết tại sao – vì phương thức session.save (Object) thực hiện nó rất tốt rồi). Vì vậy, chúng ta chỉ có thể viết INSERT … SELECT truy vấn trong HQL. Đoạn mã sau thực hiện truy vấn chèn tất cả các dòng dữ liệu từ bảng Category vào bảng OldCategory:
String hql = "insert into Category (id, name)"
+ " select id, name from OldCategory";
Query query = session.createQuery(hql);
int rowsAffected = query.executeUpdate();
if (rowsAffected > 0)
System.out.println(rowsAffected + "(s) were inserted");
Lưu ý rằng HQL là hướng đối tượng, vì vậy Category và OldCategory phải được ánh xạ các tên lớp (không phải tên bảng thật).
6. Ví dụ Update Query
Truy vấn UPDATE tương tự như SQL. Ví dụ sau chạy truy vấn cập nhật giá cho một sản phẩm cụ thể:
String hql = "update Product set price = :price where id = :id";
Query query = session.createQuery(hql);
query.setParameter("price", 488.0f);
query.setParameter("id", 43l);
int rowsAffected = query.executeUpdate();
if (rowsAffected > 0)
System.out.println("Updated " + rowsAffected + " rows.");
7. Ví dụ Delete Query
Sử dụng truy vấn DELETE trong HQL cũng dễ hiểu. Ví dụ:
String hql = "delete from OldCategory where id = :catId";
Query query = session.createQuery(hql);
query.setParameter("catId", new Long(1));
int rowsAffected = query.executeUpdate();
if (rowsAffected > 0)
System.out.println("Deleted " + rowsAffected + " rows.");
8. Ví dụ Join Query
HQL hỗ trợ các loại kết bảng Join (như SQL):
- inner join (can be abbreviated as join).
- left outer join (can be abbreviated as left join).
- right outer join (can be abbreviated as right join).
- full join
Ví dụ, đoạn lệnh dưới đây sẽ truy vấn mà kết quả trả về là Join giữa 2 bảng Product và Category:
String hql = "from Product p inner join p.category";
Query query = session.createQuery(hql);
List<Object[]> listResult = query.list();
for (Object[] aRow : listResult)
Product product = (Product) aRow[0];
Category category = (Category) aRow[1];
System.out.println(product.getName() + " - " + category.getName());
Dùng Join trên HQL là không tường minh. Chú ý rằng câu lệnh Join sẽ trả về 1 danh sách mảng Object, vì thế chúng ta cần xử lý kết quả trả về này:
List<Object[]> listResult = query.list();
HQL cung cấp từ khóa mà bạn có thể sử dụng trong trường hợp bạn muốn Join có điều kiện. Ví dụ:
from Product p inner join p.category with p.price > 500
Câu lệnh phía trên Join giữa Product và Category với nhau qua điều kiện là price của Produce > 500
Nếu bạn khó hiểu câu lệnh phía trên, chúng ta có thể viết từng minh như thế này cũng được:
from Product where category.name = 'Computer'
9. Ví dụ Sort Query
Sắp xếp trong HQL tương tự như SQL dùng lệnh ORDER BY theo đó là cột nào cần sắp xếp và sắp xếp theo hướng ASC(tăng dần) hay DESC(giảm dần). Ví dụ:
String hql = "from Product order by price ASC";
Query query = session.createQuery(hql);
List<Product> listProducts = query.list();
for (Product aProduct : listProducts)
System.out.println(aProduct.getName() + "\t - " + aProduct.getPrice());
Kết quả là lấy danh sách tất cả các sản phẩm sắp xếp tăng dần theo giá.
10. Ví dụ Group By Query
Dùng GROUP BY trong HQL tương tự SQL. Câu truy vấn dưới đây gom nhóm giá của tất cả sản phẩm cho mỗi thể loại:
select sum(p.price), p.category.name from Product p group by category
Đây là toàn bộ code:
String hql = "select sum(p.price), p.category.name from Product p group by category";
Query query = session.createQuery(hql);
List<Object[]> listResult = query.list();
for (Object[] aRow : listResult)
Double sum = (Double) aRow[0];
String category = (String) aRow[1];
System.out.println(category + " - " + sum);
11. Ví dụ Pagination Query
Truy vấn phân trang Trả về một tập hợp giới hạn các kết quả, giao diện truy vấn có 2 phương thức cho giới hạn tập kết quả:
- setFirstResult(int firstResult): thiết lập dòng đầu tiên nhận được từ kết quả truy vấn.
- setMaxResults(int maxResults): thiết lập số lượng dòng nhận được từ kết quả truy vấn.
Ví dụ, đoạn lệnh dưới đây lấy 10 sản phẩm đầu tiên từ kết quả truy vấn:
String hql = "from Product";
Query query = session.createQuery(hql);
query.setFirstResult(0);
query.setMaxResults(10);
List<Product> listProducts = query.list();
for (Product aProduct : listProducts)
System.out.println(aProduct.getName() + "\t - " + aProduct.getPrice());
12. Ví dụ Date Range Query
Một tính năng hay của Hibernate đó là nó có thể kiểm soát tham số để tạo ra kết quả SQL cho phù hợp. Nên việc dùng tham số date time trong HQL cực dễ dàng, ví dụ:
String hql = "from Order where purchaseDate >= :beginDate and purchaseDate <= :endDate";
Query query = session.createQuery(hql);
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
Date beginDate = dateFormatter.parse("2014-11-01");
query.setParameter("beginDate", beginDate);
Date endDate = dateFormatter.parse("2014-11-22");
query.setParameter("endDate", endDate);
List<Order> listOrders = query.list();
for (Order anOrder : listOrders)
System.out.println(anOrder.getProduct().getName() + " - "
+ anOrder.getAmount() + " - "
+ anOrder.getPurchaseDate());
Đoạn truy vấn trên cho kết quả các order nào có ngày mua nằm trong phạm vi ngày tháng năm.
13. Dùng Expressions trong Query
Các expressions dùng trong mệnh đề WHERE, HQL hỗ trợ tất cả các toán tử toán học tương tự như SQL bao gồm:
- mathematical operators: +, -, *, /
- binary comparison operators: =, >=, <=, <>, !=, like
- logical operators: and, or, not
- etc
Xem đầy đủ hơn tại trang chủ của Hibernate, click here.
Ví dụ, câu truy vấn dưới đây trả về các sản phẩm có giá trong phạm vi 500$ tới 1000$
from Product where price >= 500 and price <= 1000
14. Dùng Aggregate Functions trong Query
HQL hỗ trợ các hàm aggregate sau:
- avg(…), sum(…), min(…), max(…)
- count(*)
- count(…), count(distinct…), count(all…)
Ví dụ, câu truy vấn dưới đây đếm tất cả các sản phẩm:
select count(name) from Product
Và dưới đây là toàn bộ code bao gồm cách lấy kết quả:
String hql = "select count(name) from Product";
Query query = session.createQuery(hql);
List listResult = query.list();
Number number = (Number) listResult.get(0);
System.out.println(number.intValue());
XONG! Qua bài Hướng dẫn Hibernate Query Language (HQL) qua ví dụ, bạn đã biết được các kiến thức cơ bản của Hibernate Query Language (HQL). Giờ đây bạn có thể truy vấn HQL dễ dàng hơn bao giờ hết!
Hibernate Query Language (HQL) Example
Link Source: Hướng dẫn Hibernate Query Language (HQL) qua Ví Dụ