Bài 3: Hibernate Query Language (HQL) và Criteria API

·

4 min read

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 Userusername 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.