Pagination and Sorting using Spring Data JPA

Pagination and Sorting using Spring Data JPA

Pagination is often helpful when we have a large dataset and we want to present it to the user in smaller chunks.

Also, we often need to sort that data by some criteria while paging.

Initial Setup :

A Entity class that defines our table is required.

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {
    @Id
    @GeneratedValue
    private  int id;
    private String name;
    private int quantity;
    private long price;

    public Product(String name, int quantity, long price) {
        this.name = name;
        this.quantity = quantity;
        this.price = price;
    }
}

Creating a Repository :

We need to create a Repository that extends JpaRepository<YourEntity, Long>

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface YourEntityRepository extends JpaRepository<Product, Integer> {
}

JpaRepository interface extends the PagingAndSortingRepository interface so if your repository interface is of type JpaRepository, you don’t have to make a change to it.

For pagination, we are going to use the below method from the PagingAndSortingRepository interface:

    Page < T > findAll(Pageable pageable);

For sorting, we are going to use the below method from the PagingAndSortingRepository interface:

Iterable < T > findAll(Sort sort);

Implementing Pagination and Sorting in Service:

Sorting

    public List<Product> findProductsWithSorting(String field){
        return  repository.findAll(Sort.by(Sort.Direction.ASC,field));
        //First argument is the Direction of sorting can be - DESC / ASC
        //Second argument is the feild that defines the sorting
    }

Pagination

    public Page<Product> findProductsWithPagination(int offset,int pageSize){
        Page<Product> products = repository.findAll(PageRequest.of(offset, pageSize));
        return  products;
    }

Pagination With Sorting

public Page<Product> findProductsWithPaginationAndSorting(int offset,int pageSize,String field){
        Page<Product> products = repository.findAll(PageRequest.of(offset, pageSize).withSort(Sort.by(field)));
        return  products;
}

And Finally You Just needs Perfect Controllers.

    @GetMapping("/{field}")
    private APIResponse<List<Product>> getProductsWithSort(@PathVariable String field) {
        List<Product> allProducts = service.findProductsWithSorting(field);
        return new APIResponse<>(allProducts.size(), allProducts);
    }

    @GetMapping("/pagination/{offset}/{pageSize}")
    private APIResponse<Page<Product>> getProductsWithPagination(@PathVariable int offset, @PathVariable int pageSize) {
        Page<Product> productsWithPagination = service.findProductsWithPagination(offset, pageSize);
        return new APIResponse<>(productsWithPagination.getSize(), productsWithPagination);
    }

    @GetMapping("/paginationAndSort/{offset}/{pageSize}/{field}")
    private APIResponse<Page<Product>> getProductsWithPaginationAndSort(@PathVariable int offset, @PathVariable int pageSize,@PathVariable String field) {
        Page<Product> productsWithPagination = service.findProductsWithPaginationAndSorting(offset, pageSize, field);
        return new APIResponse<>(productsWithPagination.getSize(), productsWithPagination);
    }