Saturday, August 26, 2023

Difference between JpaREpository, CrudREpository, and PagingAndSortingRepository

Hello and welcome to my blog post. In this article, we will delve into the world of Spring Data repositories and explore the key differences between three commonly used interfaces: JpaRepository, CrudRepository, and PagingAndSortingRepository. If you're a Spring Boot developer working with databases, understanding the distinctions between these interfaces is crucial for efficient data management. So let's dive right in and uncover the unique features and use cases of each repository interface.
Spring Data makes it easier for Spring applications to communicate with databases. For basic database operations, it offers a set of abstractions and default implementations, making it simpler for developers to work with persistent data. Here it is important to mention, Spring Data follows a repository pattern which encourages a standardized and efficient approach to data access.


1. CrudRepository

This repository is the most basic interface for CRUD operations. It act as a foundation of Spring Data repository. It offers a collection of standard methods for performing the fundamental CRUD actions on entities such as Create, Read, Update, and Delete. 

CrudRepository is a great option if you're searching for a simple and simplest approach to data administration.

By extending CrudRepository, you can easily carry out standard database activities by using methods like save, delete, findById, and findAll. This interface acts as a abstraction with a simple design for working with persistent data. CrudRepository is still a reliable choice for many straightforward use cases even though it lacks the sophisticated JPA-specific features of JpaRepository.

2. PagingAndSortingRepository

This repository allow Pagination and Sorting, that help effective data retrieval
As you data grows, effectively retrieving and displaying of data becomes more crucial. In this situation, PagingAndSortingRepository is really handy. By adding pagination and sorting features to CrudRepository, PagingAndSortingRepository improves your ability to get data.

3. JpaRepository

This repository is the powerhouse of JPA-specific Operations
Just like the other two interfaces, JpaRepository is an interface that takes the Spring Data repository to the next level. Internally, it extends the CRUDRepository interface. It provide range of handy JPA-specific methods that help seamless operation with the underlying persistence layer.

JpaRepository not only perform routine tasks like saving entities, erasing entities, and locating entities by their main keys but also provides assistance for running customized queries via method names or annotations like @Query.

Now, we have a very good understanding of what potential does each interface have. It’s time to explore their key differences with the help of example.

Difference between JpaREpository, CrudREpository, and PagingAndSortingRepository



Example Program:

1) Create entity class ‘Product’

First, let's create an entity class called "Product" that represents a product in our application. It will have an id, name, and price.

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;



@Entity

public class Product {

    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Long id;

    

    private String name;

    private double price;

    

    // Constructors, getters, and setters

}



2) Create repository interface.

Next, we'll create the repository interfaces that extend JpaRepository, CrudRepository, and PagingAndSortingRepository.

import org.springframework.data.domain.Page;

import org.springframework.data.domain.Pageable;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;



@Repository

public interface ProductJpaRepository extends JpaRepository<Product, Long> {

    // Additional JPA-specific methods

    List<Product> findByPriceGreaterThan(double price);

}



@Repository

public interface ProductCrudRepository extends CrudRepository<Product, Long> {

    // Additional methods

    List<Product> findByNameContainingIgnoreCase(String keyword);

}



@Repository

public interface ProductPagingRepository extends PagingAndSortingRepository<Product, Long> {

    // No additional methods required

}

3) Create Application Class:


Now create a main application class to show the use case of these repositories.


import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.CommandLineRunner;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.data.domain.PageRequest;

import org.springframework.data.domain.Sort;



@SpringBootApplication

public class RepositoryDemoApplication implements CommandLineRunner {



    @Autowired

    private ProductJpaRepository productJpaRepository;



    @Autowired

    private ProductCrudRepository productCrudRepository;



    @Autowired

    private ProductPagingRepository productPagingRepository;



    public static void main(String[] args) {

        SpringApplication.run(RepositoryDemoApplication.class, args);

    }



    @Override

    public void run(String... args) throws Exception {

        // Creating and saving products

        Product product1 = new Product();

        product1.setName("Product 1");

        product1.setPrice(10.0);

        productJpaRepository.save(product1);



        Product product2 = new Product();

        product2.setName("Product 2");

        product2.setPrice(20.0);

        productCrudRepository.save(product2);



        Product product3 = new Product();

        product3.setName("Product 3");

        product3.setPrice(30.0);

        productPagingRepository.save(product3);



        // Fetching products

        System.out.println("----- Fetching Products -----");



        // JpaRepository

        System.out.println("JpaRepository:");

        List<Product> highPricedProducts = productJpaRepository.findByPriceGreaterThan(15.0);

        highPricedProducts.forEach(System.out::println);



        // CrudRepository

        System.out.println("CrudRepository:");

        List<Product> productsByName = productCrudRepository.findByNameContainingIgnoreCase("Product");

        productsByName.forEach(System.out::println);



        // PagingAndSortingRepository

        System.out.println("PagingAndSortingRepository:");

        Pageable pageable = PageRequest.of(0, 2, Sort.by("price").ascending());

        Page<Product> sortedProducts = productPagingRepository.findAll(pageable);

        sortedProducts.getContent().forEach(System.out::println);

    }

}

4) Build and run the Application:

After setting up the classes, you can build and run the Spring Boot application. It first create some sample products and fetch them using different repository interfaces.

In ProductJpaRepository, we added a method findByPriceGreaterThan(double price) to retrieve products with prices greater than a specified value.

In ProductCrudRepository, we added a method findByNameContainingIgnoreCase(String keyword) to retrieve products by searching for a keyword in their names.

In ProductPagingRepository, we used PageRequest to define pagination and sorting criteria for the findAll() method.

The findAll(Pageable pageable) method is called with a PageRequest instance to retrieve a specific page of sorted data. In this case, we define a PageRequest with page number 0, page size 2, and sorting by price in ascending order.

This code snippet fetches the first page of products with a page size of 2, sorted by price in ascending order. Using PageRequest allows you to control the pagination and sorting of query results efficiently when working with large datasets.

When you run the application, you will see the products being fetched using JpaRepository, CrudRepository, and PagingAndSortingRepository. The output will demonstrate the usage and differences between these interfaces.

JpaRepository retrieves high-priced products using the findByPriceGreaterThan() method.

CrudRepository retrieves products by searching for a keyword in their names using the findByNameContainingIgnoreCase() method.

PagingAndSortingRepository retrieves sorted and paginated products using the findAll() method with Pageable parameters.


This example illustrates the basic usage of these repository interfaces. You can further explore their capabilities by adding custom query methods or leveraging pagination and sorting features provided by PagingAndSortingRepository.




Conclusion:
In conclusion, Spring Data JPA provides interfaces called JpaRepository, CrudRepository, and PagingAndSortingRepository that simplify database operations and eliminate unnecessary boilerplate code.

Together with these repository interfaces, Spring Data JPA allow developers to concentrate on the essential business logic of their applications. It encourages efficiency, code reuse, and adherence to recommended data access procedures.

I hope this example helps you understand the difference between JpaRepository, CrudRepository, and PagingAndSortingRepository in a practical setting. Feel free to modify and enhance the code as per your requirements. Happy coding!

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.