Search…

Sự Khác Biệt giữa HQL và Criteria

17/09/20203 min read
Phân biệt HQL và Criteria, nên sử dụng HQL và Criteria trong các trường hợp cụ thể.

Hibernate hỗ trợ nhiều cách truy vấn dữ liệu trong đó có thể phân biệt làm 2 nhóm chính sau:

  • Native SQL: hỗ trợ viết truy vấn hướng thủ tục và dựa vào hệ quản trị cơ sở dữ liệu cụ thể.
  • Hướng đối tượng: Hibernate hỗ trợ viết truy vấn dạng hướng đối tượng và có 2 cách tiếp cận.
    • HQL: xây dựng truy vấn hướng đối tượng dưới dạng chuỗi.
    • Criteria: xây dựng truy vấn hướng đối tượng dưới dạng code Java.

Native SQL

Hibernate vẫn hỗ trợ Native SQL, sử dụng các câu truy vấn tùy vào hệ quản trị cơ sở dữ liệu. Với Native SQL, phụ thuộc hoàn toàn vào hệ quản trị cơ sở dữ liệu, giả sử các cú pháp truy vấn được sử dụng cho Oracle không đảm bảo sẽ tương thích với MySQL.

Giả sử có class Article và bảng articles và sử dụng MySQL.

Article.java

class Article {
    Long id;
    String title;
    String description;
    String content;
}

Bảng articles

id title description content
1 Xây Dựng Câu Truy Vấn trong Hibernate với HQL ... ...
2 Xây Dựng Câu Truy Vấn trong Hibernate với Criteria ... ...
3 Sự Khác Biệt giữa HQL và Criteria ... ...
... ... ... ...

Truy vấn

String sql = "SELECT * FROM articles";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Article.class);
List results = query.list();

Hướng đối tượng

Hibernate hỗ trợ viết truy vấn hướng đối tượng, các truy vấn này được chuyển đổi dựa trên các gói SQL Dialects khi cấu hình Hibernate, ứng với mỗi Dialect sẽ dành cho 1 hệ quản trị cơ sở dữ liệu cụ thể (kể cả phiên bản). Do đó, nếu thay đổi hệ quản trị cơ sở dữ liệu khác, chỉ cần cấu hình lại Dialect tương ứng:

  • org.hibernate.dialect.MySQLDialect
  • org.hibernate.dialect.MySQLInnoDBDialect
  • org.hibernate.dialect.ProgressDialect
  • org.hibernate.dialect.SQLServerDialect
  • ...

Cách tiếp cận này tập trung vào các class, thuộc tính, quan hệ thì được diễn đạt bằng các tham chiếu chứ không tập trung vào bảng, cột và kết bảng.

HQL

HQL tạo ra truy vấn theo phong cách hướng đối tượng, HQL thể hiện dạng chuỗi, mặc dù có cú pháp gần tương tự SQL nhưng như đề cập ở trên HQL sẽ tập trung vào class, thuộc tính và tham chiếu.

Giả sử cần truy vấn bài viết thì tập trung vào Entity (class) Article thay vì bảng articles.

String hql = "FROM Article";
Query query = session.createQuery(hql);
List results = query.list();

Criteria

Criteria tạo ra truy vấn theo phong cách hướng đối tượng, Criteria thể hiện ở dạng Java code, cách thức lập trình của Criteria linh động hơn HQL, có thể "gắn" thêm hoặc gỡ bỏ 1 yêu cầu vào truy vấn dễ dàng hơn.

Giả sử cần truy vấn bài viết thì tập trung vào Entity (class) Article thay vì bảng articles.

CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<Article> criteriaQuery = criteriaBuilder.createQuery(Article.class);
Root<Article> _article = criteriaQuery.from(Article.class); criteriaQuery.select(_article);
TypedQuery<Article> typedQuery = session.createQuery(criteriaQuery); List results = typedQuery.getResultList();

Bảng so sánh HQL và Criteria

HQL Criteria
HQL xây dựng truy vấn dựa trên định dạng chuỗi. Criteria xây dựng truy vấn dựa trên cú pháp code.
Phù hợp với các truy vấn cố định, đối với các truy vấn phức tạp, nhiều điều kiện sẽ dẫn đến việc thêm và bớt điều kiện trở nên phức tạp, rất khó để gỡ bỏ và thêm vào trong 1 chuỗi truy vấn.  Linh động hơn, có thể thêm, bớt 1 điều kiện dễ dàng, chỉ cần "cắm" hoặc "gỡ" bỏ 1 điều kiện qua các điều kiện, sắp xếp, phân trang được xây dựng thành các phương thức để gọi. 
HQL là dạng chuỗi nên vẫn có nhiều nguy cơ về Injection. Hạn chế được Injection tốt hơn HQL.

Bài chung series

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024