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.
- 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:
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.gt
là greater 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ề views
và comments
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 setFirstResult
và setMaxResults
đượ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")) |