Phân loại với JPA

1. Khái quát chung

Bài viết này minh họa các cách khác nhau mà JPA có thể được sử dụng để phân loại .

2. Sắp xếp với JPA / JQL API

Sử dụng JQL để sắp xếp được thực hiện với sự trợ giúp của mệnh đề Order By :

String jql; Query query = entityManager.createQuery (jql);

Dựa trên truy vấn này, JPA tạo câu lệnh SQL đơn giản sau:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_ from Foo foo0_ order by foo0_.id

Lưu ý rằng các từ khóa SQL trong chuỗi JQL không phân biệt chữ hoa chữ thường, nhưng tên của các thực thể và thuộc tính của chúng thì có.

2.1. Đặt thứ tự sắp xếp

Theo mặc định , thứ tự sắp xếp tăng dần , nhưng nó có thể được đặt rõ ràng trong chuỗi JQL. Cũng giống như trong SQL thuần túy, các tùy chọn sắp xếp là ascdesc :

String jql = "Select f from Foo as f order by f.id desc"; Query sortQuery = entityManager.createQuery(jql);

Sau đó, truy vấn SQL được tạo sẽ bao gồm hướng thứ tự:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_ from Foo foo0_ order by foo0_.id desc

2.2. Sắp xếp theo nhiều thuộc tính

Để sắp xếp theo nhiều thuộc tính, các thuộc tính này được thêm vào mệnh đề o rder by của chuỗi JQL:

String jql; Query sortQuery = entityManager.createQuery(jql);

Cả hai điều kiện sắp xếp sẽ xuất hiện trong câu lệnh truy vấn SQL được tạo :

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_ from Foo foo0_ order by foo0_.name asc, foo0_.id desc

2.3. Đặt mức độ ưu tiên sắp xếp của các giá trị rỗng

Ưu tiên mặc định của null là cơ sở dữ liệu cụ thể, nhưng điều này có thể tùy chỉnh thông qua mệnh đề NULLS FIRST hoặc NULLS LAST trong chuỗi truy vấn HQL.

Đây là một ví dụ đơn giản - sắp xếp theo tên của Foo theo thứ tự giảm dần và đặt Null s ở cuối:

Query sortQuery = entityManager.createQuery ("Select f from Foo as f order by f.name desc NULLS LAST");

Truy vấn SQL được tạo bao gồm mệnh đề kết thúc 1 else 0 rỗng (dòng thứ 3):

Hibernate: select foo0_.id as id1_4_, foo0_.BAR_ID as BAR_ID2_4_, foo0_.bar_Id as bar_Id2_4_, foo0_.name as name3_4_,from Foo foo0_ order by case when foo0_.name is null then 1 else 0 end, foo0_.name desc

2.4. Sắp xếp một thành nhiều mối quan hệ

Chuyển qua các ví dụ cơ bản, bây giờ chúng ta hãy xem xét một trường hợp sử dụng liên quan đến việc sắp xếp các thực thể theo mối quan hệ từ một đến nhiều - Thanh chứa tập hợp các thực thể Foo .

Chúng tôi muốn sắp xếp các thực thể Bar và cả tập hợp các thực thể Foo của chúng - JPA đặc biệt đơn giản cho nhiệm vụ này:

  1. Sắp xếp bộ sưu tập: Thêm một OrderBy chú thích trước Foo bộ sưu tập trong Bar thực thể:
    @OrderBy("name ASC") List  fooList;
  2. Sắp xếp đối tượng chứa tập hợp:
    String jql = "Select b from Bar as b order by b.id"; Query barQuery = entityManager.createQuery(jql); List barList = barQuery.getResultList();

Lưu ý rằng chú thích @OrderBy là tùy chọn, nhưng chúng tôi đang sử dụng nó trong trường hợp này vì chúng tôi muốn sắp xếp bộ sưu tập Foo của mỗi Thanh .

Chúng ta hãy xem truy vấn SQL được gửi đến RDMS:

Hibernate: select bar0_.id as id1_0_, bar0_.name as name2_0_ from Bar bar0_ order by bar0_.id Hibernate: select foolist0_.BAR_ID as BAR_ID2_0_0_, foolist0_.id as id1_4_0_, foolist0_.id as id1_4_1_, foolist0_.BAR_ID as BAR_ID2_4_1_, foolist0_.bar_Id as bar_Id2_4_1_, foolist0_.name as name3_4_1_ from Foo foolist0_ where foolist0_.BAR_ID=? order by foolist0_.name asc 

Truy vấn đầu tiên sắp xếp thực thể Bar mẹ . Truy vấn thứ hai được tạo để sắp xếp tập hợp các thực thể Foo con thuộc Bar .

3. Sắp xếp với API đối tượng truy vấn tiêu chí JPA

Với JPA Criteria - phương thức orderBy là một phương pháp thay thế “một cửa” để đặt tất cả các tham số sắp xếp: cả hướng thứ tự và các thuộc tính cần sắp xếp đều có thể được đặt. Sau đây là API của phương pháp:

  • orderBy ( CriteriaBuilder.asc ): Sắp xếp theo thứ tự tăng dần.
  • orderBy ( CriteriaBuilder.desc ): Sắp xếp theo thứ tự giảm dần.

Mỗi cá thể Order được tạo bằng đối tượng C riteriaBuilder thông qua các phương thức asc hoặc desc của nó .

Đây là một ví dụ nhanh - sắp xếp Foos theo tên của chúng :

CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Foo.class); Root from = criteriaQuery.from(Foo.class); CriteriaQuery select = criteriaQuery.select(from); criteriaQuery.orderBy(criteriaBuilder.asc(from.get("name")));

Đối số của phương thức ge t phân biệt chữ hoa chữ thường, vì nó cần phải khớp với tên của thuộc tính.

Trái ngược với JQL đơn giản, API đối tượng truy vấn tiêu chí JPA buộc một hướng thứ tự rõ ràng trong truy vấn. Lưu ý trong dòng cuối cùng của đoạn mã này rằng đối tượng criteriaBuilder chỉ định thứ tự sắp xếp tăng dần bằng cách gọi phương thức asc của nó .

Khi mã trên được thực thi, JPA tạo truy vấn SQL được hiển thị bên dưới. Đối tượng tiêu chí JPA tạo một câu lệnh SQL với mệnh đề asc rõ ràng :

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_ from Foo foo0_ order by foo0_.name asc

3.1. Sắp xếp theo nhiều thuộc tính

Để sắp xếp theo nhiều thuộc tính, chỉ cần chuyển một thể hiện Order đến phương thức orderBy cho mỗi thuộc tính để sắp xếp theo.

Đây là một ví dụ nhanh - sắp xếp theo tênid , theo thứ tự ascdesc , tương ứng:

CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Foo.class); Root from = criteriaQuery.from(Foo.class); CriteriaQuery select = criteriaQuery.select(from); criteriaQuery.orderBy(criteriaBuilder.asc(from.get("name")), criteriaBuilder.desc(from.get("id")));

Truy vấn SQL tương ứng được hiển thị bên dưới:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_ from Foo foo0_ order by foo0_.name asc, foo0_.id desc

4. Kết luận

Bài viết này khám phá các lựa chọn thay thế sắp xếp trong Java Persistence API, cho các thực thể đơn giản cũng như cho các thực thể trong mối quan hệ một-nhiều. Những cách tiếp cận này ủy thác gánh nặng của công việc sắp xếp cho lớp cơ sở dữ liệu.

Việc triển khai Hướng dẫn sắp xếp JPA này có thể được tìm thấy trong dự án GitHub - đây là một dự án dựa trên Maven, vì vậy nó sẽ dễ dàng nhập và chạy như nó vốn có.