Giới thiệu về API tiêu chí

Có hai cách để viết truy vấn cơ sở dữ liệu trong Hibernate:

  • Ngôn ngữ truy vấn ngủ đông
  • API tiêu chí

Bạn đã gặp người đầu tiên từ lâu, đã đến lúc làm quen với API tiêu chí. Đây là một công cụ rất mạnh, có thời điểm nó còn phổ biến hơn cả HQL. Bây giờ nó không còn phổ biến nữa, nhưng đối với một số tác vụ, nó chắc chắn sẽ là một giải pháp tốt hơn HQL.

Trong mọi trường hợp, bạn không thể học Hibernate mà không làm quen với Criteria API. Hãy viết một ví dụ nhỏ, và sau đó chúng tôi sẽ phân tích nó. Ví dụ: chúng tôi sẽ yêu cầu tất cả nhân viên (Employee) từ cơ sở dữ liệu. Đây là những gì chúng ta sẽ nhận được:

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Employee> critQuery = builder.createQuery(Employee.class);

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Query<Employee> query = session.createQuery(critQuery);
List<Employee> results = query.getResultList();

Có vẻ phức tạp. Hãy viết cùng một truy vấn HQL để so sánh:

String hqlQuery = "from Employee";

Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();

Lưu ý rằng hai dòng cuối cùng của cả hai ví dụ gần như giống hệt nhau: chúng tôi tạo một đối tượng Truy vấn và sử dụng nó để lấy Danh sách. Điều này gợi ý rằng phần còn lại của các dòng đang làm điều gì đó giống hệt nhau.

Nhìn vào dòng 3 và 4 của ví dụ đầu tiên:

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Hãy viết chúng trong một dòng:

critQuery.select(critQuery.from(Employee.class));

Nó không nhắc nhở bạn về bất cứ điều gì? Và nếu bạn tô màu nó hơi khác một chút:

critQuery.select(critQuery.from(Employee.class));

Vâng, đây là một cấu trúc phức tạp của truy vấn CHỌN TỪ.

Ví dụ về cách làm việc với API tiêu chí

Để hiểu rõ hơn, tôi sẽ chỉ đưa ra một vài ví dụ.

Yêu cầu 1 . Nhận tất cả nhân viên có mức lương trên 10 nghìn:

critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));

Yêu cầu 2 . Nhận tất cả nhân viên lương dưới 50 nghìn:

critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));

Yêu cầu 3 . Lấy tất cả nhân viên có chức danh công việc chứa từ "kiểm tra":

critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));

Yêu cầu 4 . Nhận tất cả nhân viên với mức lương từ 10 đến 50 nghìn:

critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));

Yêu cầu 5 . Nhận tất cả nhân viên có tên là null:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));

Yêu cầu 6 . Nhận tất cả nhân viên có tên không phải là null:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));

Đó chỉ là một cách phức tạp để xây dựng một truy vấn:

  • Đầu tiên bạn lấy đối tượngTiêu chíBuilder.
  • Sau đó sử dụng nó để tạo một đối tượngTiêu chíTruy vấn.
  • Sau đó, bạn bắt đầu thêm các bộ phận vào nó vớiTiêu chíTruy vấnTiêu chíBuilder.

Đây là cách bạn có thể đặt tham số cho:

  • LỰA CHỌN
  • TỪ
  • Ở ĐÂU

Cũng sử dụngTiêu chíBuilderbạn có thể xây dựng các điều kiện khác nhau cho WHERE.

Công việc nâng cao với API tiêu chí

Sử dụng API Tiêu chí, bạn có thể tạo truy vấn ở bất kỳ độ phức tạp nào. Và đây là một tin tuyệt vời. Ví dụ, bạn muốn một mệnh đề WHERE phức tạp. Đây là cách để làm điều đó:

Predicate greaterThan = builder.gt(root.get("salary"), 1000);
Predicate testers = builder.like(root.get("occupation"), "test%");

critQuery.select(critQuery.from(Employee.class)).where(builder.or(greaterThan, testers));

Nếu bạn muốn viết AND thay vì OR thì chỉ cần sửa dòng cuối cùng:

critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));

Mọi thứ thực ra rất đơn giản. Hãy để tôi cung cấp cho bạn một bảng với một vài so sánh:

SQL Phương pháp hồ sơ đầy đủ
a<b nó (a, b) builder.lt(a, b)
một > b gt(a, b) builder.gt(a, b)
một HOẶC b hoặc (a,b) builder.or(a, b)
A và B và (a, b) builder.and(a,b)
một THÍCH b như(a,b) người xây dựng.like(a, b)
GIỮA (c, d) giữa (a, c, d) builder.between(a, c, d)
LÀ KHÔNG làNull(a) builder.isNull(a)
KHÔNG PHẢI LÀ NULL isNotNull(a) builder.isNotNull(a)

Mọi thứ thật đơn giản phải không nào?

Và làm cách nào để thêm phân loại vào truy vấn? Rất đơn giản:

critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )

Bạn chỉ cần gọi đối tượngTiêu chíTruy vấnorderBy () và truyền các tham số cần thiết cho nó.

Đây là cách truy vấn tương tự sẽ trông như thế nào trong HQL. So sánh:

select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc

Bạn chỉ cần nhớ 3 điều:

  • Các toán tử chính như SELECT, FROM, WHERE được gọi trên một đối tượngTiêu chíTruy vấn.
  • Các toán tử phụ trợ như AND, OR, DESC được gọi trên đối tượngTiêu chíBuilder.
  • Tên trường được lấy từ đối tượng thông qua get()nguồn gốc.