Học viên: Lương Quốc

Lớp: Java Fulltack 15

Email: quoc200799@gmail.com


1.Tổng quan

Phân trang thường hữu ích khi chúng tôi có một tập dữ liệu lớn và chúng ta muốn trình bày nó cho người dùng theo các phần nhỏ hơn.

Ngoài ra, chúng ta cần sắp xếp dữ liệu đó theo một số tiêu chí trong khi phân trang.

Trong bài viết này, chúng ta sẽ tìm hiểu cách sử dụng phân trang và sắp xếp bằng Spring Data JPA.

2. Cài đặt

Đầu tiên, chúng ta có 1 entity là Product:

   @Entity 
public class Product {
    
    @Id
    private long id;
    private String name;
    private double price; 

    // constructors, getters and setters 

}

Mỗi phiên bản Product của chúng ta có một số nhận dạng identifier như: id, name và price của Product được liên kết với Product.

3. Tạo một Repository

Để truy cập Product, chúng ta sẽ cần một ProductRepository:

public interface ProductRepository extends PagingAndSortingRepository<Product, Integer> {

    List<Product> findAllByPrice(double price, Pageable pageable);
}

Bằng cách extends PagingAndSortingRepository, chúng ta lấy phương thức findAll(Pageable pageable) và findAll(Sort sort) để phân trang và sắp xếp.

Ngược lại, thay vào đó, chúng ta có thể chọn extends JpaRepository, vì nó cũng extends PagingAndSortingRepository.

Một khi chúng ta extends PagingAndSortingRepository,chúng ta có thể tạo hàm của mình rồi lấy Pageable và Sort làm tham số, giống như chúng ta đã làm với findAllByPrice như trên.

4. Phân trang

Sau khi chúng ta có repository extends từ PagingAndSortingRepository, chúng ta chỉ cần:

  1. Tạo hoặc lấy đối tượng PageRequest, đây là khi implements Pageable của interface
  2. Chuyển đối tượng PageRequest làm đối số cho hàm trong repository mà chúng ta dự định sử dụng

Chúng ta có thể tạo một đối tượng PageRequest bằng cách chuyển vào số trang được yêu cầu và kích thước trang.

Ở đây số trang bắt đầu từ 0:

Pageable firstPageWithTwoElements = PageRequest.of(0, 2);

Pageable secondPageWithFiveElements = PageRequest.of(1, 5);

Trong Spring MVC, chúng ta có thể chọn phiên bản Pageable trong cotroller của họ tại Spring Data Web Support

Khi chúng ta có đối tượng PageRequest của mình, chúng ta có thể chuyển nó vào trong khi gọi phương thức tại repository:

Page<Product> allProducts = productRepository.findAll(firstPageWithTwoElements);
List<Product> allTenDollarProducts = 
  productRepository.findAllByPrice(10, secondPageWithFiveElements);

Phương thức findAll(Pageable pageable) mặc định trả về một đối thương Page<?>.

Tuy nhiên, chúng ta có thể chọn trả về Page, một Slice hoặc List<?> từ bất kỳ phương thức tùy chỉnh nào của chúng ta khi trả về dữ liệu được phân trang.

Phiên bản Page, ngoài việc có danh sách Product, còn biết về tổng số trang có sẵn. **Nó kích hoạt một truy vấn đếm bổ sung để đạt được nó. Để tránh phí cao như vậy, chúng ta có thể trả về Slice hoặc List<?>.**

Một Slice chỉ biết liệu slice tiếp theo có sẵn hay không.

5. Phân trang và sắp xếp

Tương tự, để chỉ sắp xếp kết quả truy vấn, chúng ta chỉ cần sử dụng Sort như sau:

Page<Product> allProductsSortedByName = productRepository.findAll(Sort.by("name"));

Tuy nhiên, nếu chúng ta muốn vừa sắp xếp vừa phân trang dữ liệu của mình thì sao?

Chúng ta có thể làm điều đó bằng cách chuyển các chi tiết sắp xếp vào chính đối tượng PageRequest của mình:

Pageable sortedByName = 
  PageRequest.of(0, 3, Sort.by("name"));

Pageable sortedByPriceDesc = 
  PageRequest.of(0, 3, Sort.by("price").descending());

Pageable sortedByPriceDescNameAsc = 
  PageRequest.of(0, 5, Sort.by("price").descending().and(Sort.by("name")));

Dựa trên các yêu cầu sắp xếp của chúng ta, chúng ta có thể chỉ định các trường sắp xếp và hướng sắp xếp khi tạo PageRequest của mình.

Như thường lệ, chúng ta có thể chuyển kiểu Pageable này sang phương thức của repository riêng của ta.

6. Kết luận

Trong bài viết này, chúng ta đã học cách phân trang và sắp xếp kết quả truy vấn trong Spring Data JPA. Như mọi khi, các ví dụ mã hoàn chỉnh được sử dụng trong bài viết này đều có trên Github