Bài 3: Hibernate Query Language (HQL) và Criteria API
Bài 3: Hibernate Query Language (HQL) và Criteria API
1. Giới thiệu về HQL
HQL là gì? Hibernate Query Language (HQL) là một ngôn ngữ truy vấn hướng đối tượng tương tự như SQL nhưng hoạt động trên các đối tượng Java thay vì các bảng cơ sở dữ liệu. HQL cho phép lập trình viên viết các truy vấn phức tạp với cú pháp đơn giản và dễ hiểu hơn.
Khác biệt giữa HQL và SQL
HQL: Làm việc với các đối tượng và thuộc tính của đối tượng Java.
SQL: Làm việc trực tiếp với các bảng và cột trong cơ sở dữ liệu.
HQL cung cấp các tính năng mạnh mẽ như inheritance, polymorphism, và association.
2. Sử dụng HQL để truy vấn dữ liệu
Truy vấn đơn giản: SELECT, FROM, WHERE
SELECT: Chọn các đối tượng hoặc thuộc tính cần truy vấn.
FROM: Chỉ định lớp entity cần truy vấn.
WHERE: Điều kiện lọc các đối tượng.
Ví dụ cụ thể
Session session = HibernateUtil.getSessionFactory().openSession();
String hql = "FROM User WHERE username = :username";
Query query = session.createQuery(hql);
query.setParameter("username", "johndoe");
List<User> results = query.list();
session.close();
Đoạn mã trên truy vấn các đối tượng User
có thuộc tính username
bằng "johndoe".
Truy vấn với JOIN, ORDER BY, GROUP BY
JOIN: Kết hợp các entity có quan hệ với nhau.
ORDER BY: Sắp xếp kết quả truy vấn.
GROUP BY: Nhóm kết quả truy vấn theo một thuộc tính.
Ví dụ cụ thể về JOIN
String hql = "SELECT u FROM User u JOIN u.addresses a WHERE a.city = :city";
Query query = session.createQuery(hql);
query.setParameter("city", "Hometown");
List<User> results = query.list();
Đoạn mã trên truy vấn các đối tượng User
có địa chỉ (address) trong thành phố "Hometown".
Ví dụ cụ thể về ORDER BY
String hql = "FROM User ORDER BY username ASC";
Query query = session.createQuery(hql);
List<User> results = query.list();
Đoạn mã trên truy vấn tất cả các đối tượng User
và sắp xếp chúng theo username
tăng dần.
Ví dụ cụ thể về GROUP BY
String hql = "SELECT a.city, COUNT(u) FROM User u JOIN u.addresses a GROUP BY a.city";
Query query = session.createQuery(hql);
List<Object[]> results = query.list();
Đoạn mã trên đếm số lượng người dùng trong từng thành phố và nhóm kết quả theo city
.
3. Giới thiệu về Criteria API
Criteria API là gì? Criteria API là một API cung cấp các phương thức để xây dựng các truy vấn động bằng cách sử dụng các đối tượng Java thay vì viết các chuỗi truy vấn HQL. Điều này giúp truy vấn an toàn hơn và dễ dàng hơn khi cần xây dựng các truy vấn phức tạp.
Ưu điểm của Criteria API so với HQL
Động và linh hoạt: Truy vấn có thể được xây dựng động dựa trên các điều kiện runtime.
An toàn kiểu: Sử dụng các đối tượng và phương thức, giảm thiểu lỗi cú pháp.
Dễ đọc và bảo trì: Mã nguồn rõ ràng và dễ hiểu hơn.
4. Sử dụng Criteria API để truy vấn dữ liệu
Ví dụ cụ thể về truy vấn với Criteria API
Session session = HibernateUtil.getSessionFactory().openSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);
query.select(root).where(builder.equal(root.get("username"), "johndoe"));
Query<User> q = session.createQuery(query);
List<User> results = q.getResultList();
session.close();
Đoạn mã trên truy vấn các đối tượng User
có username
bằng "johndoe" bằng cách sử dụng Criteria API.
So sánh giữa HQL và Criteria API
HQL:
Viết nhanh và ngắn gọn cho các truy vấn đơn giản.
Khó bảo trì và dễ lỗi cú pháp cho các truy vấn phức tạp.
Criteria API:
Linh hoạt và dễ dàng xây dựng các truy vấn động.
Mã nguồn dài hơn nhưng rõ ràng và dễ hiểu.
Các thao tác khác với Criteria API
Truy vấn với JOIN
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);
Join<User, Address> addresses = root.join("addresses");
query.select(root).where(builder.equal(addresses.get("city"), "Hometown"));
List<User> results = session.createQuery(query).getResultList();
Đoạn mã trên truy vấn các đối tượng User
có địa chỉ trong thành phố "Hometown" bằng cách sử dụng JOIN trong Criteria API.
Truy vấn với ORDER BY
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);
query.select(root).orderBy(builder.asc(root.get("username")));
List<User> results = session.createQuery(query).getResultList();
Đoạn mã trên truy vấn tất cả các đối tượng User
và sắp xếp chúng theo username
tăng dần bằng Criteria API.
Truy vấn với GROUP BY
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Object[]> query = builder.createQuery(Object[].class);
Root<User> root = query.from(User.class);
Join<User, Address> addresses = root.join("addresses");
query.multiselect(addresses.get("city"), builder.count(root)).groupBy(addresses.get("city"));
List<Object[]> results = session.createQuery(query).getResultList();
Đoạn mã trên đếm số lượng người dùng trong từng thành phố và nhóm kết quả theo city
bằng Criteria API.
Qua bài hướng dẫn này, bạn đã nắm được cách sử dụng HQL và Criteria API để truy vấn dữ liệu trong Hibernate. Những kiến thức này sẽ giúp bạn linh hoạt và hiệu quả hơn trong việc truy vấn và quản lý dữ liệu trong các ứng dụng Java sử dụng Hibernate.