Spring Data Repository

Introduction to String Data Repositories

Spring Data JPA simplifies the implementation of data access layers by providing a repository abstraction over the persistence layer. Repository in Spring Data help you reduce boilerplate code by providing out-of-the-box CURD operations, custom queries, and more. This approach enables you to focus on your application’s business logic while relying on Spring Data to handle the persistence details.

Creating a Simple CRUD Repository

Spring Data provides interfaces like CrudRepository, PagingAndSortingRepository and JpaRepository to handle CRUD operations. You can create a simple CRUD repository by extending one of these interfaces.

import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Long> {
    // No need to write implementation code; Spring Data JPA does it for you
}

  • CrudRepository: Provides methods like save, findById, findAll, deleteById…
  • JpaRepository: Extends CrudRepository and adds additional methods like flush, saveAndFlush and others..

By extending these interfaces, you gain access to standard data access methods without writing any implementation code.

Custom Query Methods

Spring Data JPA allows you to define custom query methods by simply declaring method signatures in your repository interface. The method names follow a specific naming convention based on the entity’s fields.

import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Long> {
    List<User> findByLastName(String lastName);
    User findByEmail(String email);
}

Spring Data automatically translate these method names into SQL queries based on your entity structure, providing an easy way to create a custom queries.

@Query Annotation: Writing JPQL and Native SQL Queries

While Spring Data can automatically generate queries for simple method names, you may need more complex queries that require the @Query annotation

JPQL Queries: These are object-oriented queries that work with your entity models rather than the database tables directly.

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Long> {

    @Query("SELECT u FROM User u WHERE u.email = ?1")
    User findUserByEmail(String email);
}

Native SQL Queries: If you need to write raw SQL, you can set the nativeQuery attribute to true in the @Query annotation

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Long> {

    @Query(value = "SELECT * FROM users WHERE email = ?1", nativeQuery = true)
    User findUserByEmailNative(String email);
}

Pagination and Soring with Repositories

Handling large datasets efficiently requires pagination and sorting. Spring Data JPA makes this easy with the PagingAndSortingRepository interface, which provides methods for both.

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;

public interface UserRepository extends PagingAndSortingRepository<User, Long> {
    Page<User> findAll(Pageable pageable);
}

To use pagination and sorting, your create a PageRequest object:

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;

PageRequest pageable = PageRequest.of(0, 10, Sort.by("lastName").ascending());
Page<User> page = userRepository.findAll(pageable);

for (User user : page) {
    System.out.println(user.getLastName());
}

Spring Data JPA methods convention

Spring Data JPA uses a set of conventions for deriving query methods based on the method names you define in your repository interfaces. These naming conventions allow Spring Data to automatically generate queries for you, based on your method names. Below are the rules and conventions for defining query methods:

  • Keyword: Specifies the operation (find, read, get, count, delete)
  • Subject: The entity attribute you’re querying (ByFirstName, ByLastNameAndAge)
  • Conditions: The conditions under which the query should be executed (GreaterThan, LessThan, Like, Between)

KeyWords

  • find…By: Retrieves one or more entities.
  • read…By: Similar to find…By, retrieves one or more entities.
  • get…By: Similar to find…By, retrieves one or more entities.
  • count…By: Counts the number of entities matching the criteria.
  • delete…By: Deletes entities matching the criteria.
  • exists…By: Checks if an entity matching the criteria exists.
List<User> findByLastName(String lastName);

Property Expression

Property expressions are based on the entity’s fields. If your entity has a field firstName you can create a query method like:

  • Simple Condition: findByFirstName(String firstName)
  • Multiple Conditions: Combine property expressions using And, Or. Ex: findByFirstNameAndLastName(String firstName, String lastname)

Operators

  • And: Combines two conditions with a logical AND.
    • Example: findByFirstNameAndLastName(String firstName, String lastName)
  • Or: Combines two conditions with a logical OR.
    • Example: findByFirstNameOrLastName(String firstName, String lastName)
  • Is, Equals: Checks for equality.
    • Example: findByFirstNameIs(String firstName), findByFirstNameEquals(String firstName)
  • Between: Checks if a value is between two values.
    • Example: findByAgeBetween(int start, int end)
  • LessThan, GreaterThan: Checks for less than or greater than conditions.
    • Example: findByAgeLessThan(int age), findByAgeGreaterThan(int age)
  • Like: Performs a SQL LIKE query.
    • Example: findByFirstNameLike(String pattern)
  • StartingWith, EndingWith, Containing: Variants of LIKE for prefix, suffix, or substring matches.
    • Example: findByFirstNameStartingWith(String prefix), findByFirstNameEndingWith(String suffix), findByFirstNameContaining(String substring)
  • In, NotIn: Checks if a value is within or outside a collection.
    • Example: findByAgeIn(Collection ages), findByAgeNotIn(Collection ages)
  • True, False: Checks for boolean fields.
    • Example: findByActiveTrue(), findByActiveFalse()
  • OrderBy: Sorts the results by the specified fields.
    • Example: findByLastNameOrderByFirstNameAsc(String lastName)

Special Handling for Null Values

  • IsNull, isNotNull: Checks for null or non-null values. Ex: findByMiddleNameIsNull()

Limit and Pagination

  • First, Top: Limits the number of results returned.
    • Ex: FindFirstByOrderByLastNameAsc(), findTop3ByAgeDesc()
import org.springframework.data.repository.CrudRepository;
import java.util.List;

public interface UserRepository extends CrudRepository<User, Long> {
    
    // Simple equality condition
    List<User> findByFirstName(String firstName);
    
    // Combining conditions with AND
    List<User> findByFirstNameAndLastName(String firstName, String lastName);
    
    // Using OR condition
    List<User> findByFirstNameOrLastName(String firstName, String lastName);
    
    // Using relational operators
    List<User> findByAgeGreaterThan(int age);
    
    // Using LIKE for pattern matching
    List<User> findByLastNameLike(String pattern);
    
    // Checking for null
    List<User> findByMiddleNameIsNull();
    
    // Sorting results
    List<User> findByLastNameOrderByFirstNameAsc(String lastName);
    
    // Limiting results
    User findFirstByOrderByAgeDesc();
}

Conclusion

Spring Data Repositories provide a powerful and flexible way to interact with databases in a Spring application. By leveraging the power of Spring Data, you can easily implement CURD operations, define custom queries, and manage pagination and sorting without writing boilerplate code. Whether you’re working with simple CRUD operations or complex queries, Spring Data JPA simplifies the data access layer, enabling you to focus on developing your application’s business logic.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top