Search…

Xây Dựng Câu Truy Vấn trong Hibernate với Criteria

17/09/20204 min read
Hướng dẫn sử dụng Criteria tạo truy vấn theo phương pháp lập trình hướng đối tượng và Java code với Hibernate.

Framework Hibernate cho phép sử dụng 3 cách để tạo ra truy vấn:

  • Native SQL: truy vấn phụ thuộc vào hệ quản trị cơ sở dữ liệu cụ thể, loại truy vấn này chỉ đáp ứng phù hợp nhất với hệ quản trị cơ sở dữ liệu đang làm việc.
  • Hibernate cung cấp 2 cách khác nhau làm việc với hệ quản trị cơ sở dữ liệu, tạo ra mã trung gian và khi cần chuyển đổi sẽ có bộ chuyển đổi phù hợp, cả 2 cách này đều có cách sử dụng theo phong cách lập trình hướng đối tượng.
    • HQL: tiếp cận dạng chuỗi gần giống với Native SQL nhưng các truy vấn sẽ nhắm vào các Entity. Ví dụ có bảng: accounts và Entity là Account thì trong truy vấn sẽ là Account.
    • Criteria: tiếp cận dạng hướng đối tượng hoàn toàn, Criteria giúp tạo ra các truy vấn theo phong cách code chứ không phải dạng chuỗi như HQL, và nó có thể biến đổi câu truy vấn tùy thuộc vào điều kiện truyền vào.

Giữa HQL và Criteria còn nhiều sự khác biệt, để phân biệt rõ hơn có thể đọc thêm bài viết này.

Câu truy vấn cơ bản với Criteria

Lấy tất cả dòng dữ liệu trong bảng articles và đưa vào danh sách đối tượng Article (Entity).

HQL

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

Với Criteria, có thể "code" câu truy vấn như sau.

Criteria

Criteria ctr = session.createCriteria(Article.class);
List results = ctr.list();

Đoạn code với Criteria cho cùng kết quả nhưng với cách tiếp cận khác, nó hoàn toàn là code Java.

Restrictions - điều kiện

Lấy tất cả dòng dữ liệu trong bảng articles và đưa vào danh sách đối tượng Article (Entity) có số views lớn hơn 10.000.

HQL

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

Nếu sử dụng Criteria, điều kiện WHERE có thể sử dụng Restrictions.

Criteria

Criteria ctr = session.createCriteria(Article.class);
ctr.add(Restrictions.gt("views", 10000));
List results = ctr.list();

add(Criterion ctn) sẽ thêm 1 điều kiện vào query, với Restrictions là lớp chứa các phép so sánh cần thiết.

Ở đoạn code trên, query sử dụng Restrictions.gtgreater than (lớn hơn), lấy các dữ liệu thỏa Article.views > 10000.

Các phương thức dựng sẵn của Restrictions

Restriction Description Example
Restrictions.gt Greater Than - giá trị so sánh phải lớn hơn số X ctr.add(Restrictions.gt("views", 10000))
Restrictions.lt Less Than - giá trị so sánh phải nhỏ hơn số X ctr.add(Restrictions.lt("views", 10000))
Restrictions.like Tìm đối tượng có giá trị tương đương, giống nhau, không phân biệt hoa thường ctr.add(Restrictions.like("title", "HQL", MatchMode.ANYWHERE))
Restrictions.ilike Tương tự like, nhưng có phân biệt hoa thường ctr.add(Restrictions.ilike("title", "HqL", MatchMode.ANYWHERE))
Restrictions.between Giá trị phải trong khoảng X và Y ctr.add(Restrictions.between("views", 5000, 10000))
Restrictions.isNull Kiểm tra thuộc tính NULL hay không ctr.add(Restrictions.isNull("date_created"))
Restrictions.isNotNull Kiểm tra thuộc tính có khác NULL hay không ctr.add(Restrictions.isNotNull("date_created"))
Restrictions.isEmpty Kiểm tra thuộc tính có rỗng hay không ctr.add(Restrictions.isEmpty("title"))
Restrictions.isNotEmpty Kiểm tra thuộc tính có khác rỗng hay không ctr.add(Restrictions.isNotEmpty("title"))
Restrictions.and Kết hợp AND giữa các điều kiện Sẽ giải thích thêm ở mục tiếp theo
Restrictions.or Kết hợp OR giữa các điều kiện Sẽ giải thích thêm ở mục tiếp theo

and/or

LogicalExpression hỗ trợ sử dụng and/or trong câu truy vấn.

Criteria ctr = session.createCriteria(Articles.class);
Criterion views = Restriction.gt("views", 10000); Criterion comments = Restriction.gt("comments", 10); LogicalExpression andExp = Restrictions.and(views, comments); ctr.add(andExp); LogicalExpression orExp = Restrictions.or(views, comments); ctr.add(orExp);
List results = ctr.list();

Khác với các ví dụ trước, khi sử dụng LogicalExpression, không add trực tiếp điều kiện về viewscomments mà kết hợp chúng lại bằng Restrictions.and hoặc Restrictions.or, sau đó mới add này vào ctr.

Paging - phân trang

Sử dụng setFirstResultsetMaxResults được cung cấp bởi lớp Criteria.

Criteria ctr = session.createCriteria(Article.class);
ctr.setFirstResult(11); ctr.setMaxResults(20);
List results = ctr.list();

Câu truy vấn sẽ lấy dữ liệu từ vị trí thứ 11 đến 20 (trang 2, mỗi trang 10 kết quả).

Sorting - Sắp xếp

Để sắp xếp các kết quả của truy vấn, sử dụng addOrder(), với tham số là Order.desc() hoặc Order.asc().

Criteria ctr = session.createCriteria(Article.class);
ctr.add(Restrictions.gt("views", 10000));
ctr.addOrder(Order.desc("views"));
List results = ctr.list();

Để thêm nhiều Order, có thể làm như sau.

ctr.addOrder(Order.desc("views"));
ctr.addOrder(Order.desc("comments"));

Hàm tính toán

Tương tự với Restrictions, có thể thêm các phép tính với giá trị vào câu truy vấn sử dụng setProjection.

Criteria ctr = session.createCriteria(Articles.class);
ctr.setProjection(Projections.rowCount());
List results = ctr.list(); if (!results.isEmpty()) { Integer rowCount = (Integer) results.get(0); System.out.println("Number of rows: " + rowCount); }

Projections.rowCount() đếm số lượng dữ liệu có trong danh sách dữ liệu và trả về 1 Integer.

Các phương thức dựng sẵn của Projections

Projection Description Example
Projections.rowCount Đếm tổng số đối tượng (dòng) trong lớp ctr.setProjection(Projections.rowCount())
Projections.avg Tính trung bình giá trị của thuộc tính (cột) ctr.setProjection(Projections.avg("views"))
Projections.countDistinct Đếm số đối tượng (không trùng lắp) trong lớp ctr.setProjection(Projections.countDistinct("author"))
Projections.max Lấy giá trị lớn nhất của thuộc tính ctr.setProjection(Projections.max("views"))
Projections.min Lấy giá trị nhỏ nhất của thuộc tính ctr.setProjection(Projections.min("views"))
Projections.sum Tính tổng các giá trị trong thuộc tính ctr.setProjection(Projections.sum("views"))

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