Derived Query Methods in Spring Data JPA Repositories
Last Updated :
20 Aug, 2024
Spring Data JPA helps manage database operations in Java applications with ease. One powerful feature is derived query methods, which let you perform common database queries by just naming the method. This way, you don’t have to write complex SQL or JPQL queries manually. Instead, you can use simple method names to search, sort, and filter your data, making your code cleaner and easier to maintain.
Benefits of Spring Data JPA Repositories
- Encapsulation: Repository interfaces isolate data access logic for each entity.
- Maintenance: Changes to data access methods are confined to specific repository interfaces.
- Type Safety: Interfaces provide strong typing for entity operations.
- Modularity and Clarity: Each repository focuses on a single entity type, ensuring that repository methods are concise and relevant.
Implementation of Derived Query Methods
Here is the step-by-step process for derived query methods in Spring Data JPA Repositories:
Step 1: Define the Entity
Create an entity class to represent the database table. For example, the AppUser
entity:
Java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.time.ZonedDateTime;
@Table(name = "app_users")
@Entity
public class AppUser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer userId;
private String fullName;
private Integer userAge;
private ZonedDateTime dateOfBirth;
private Boolean isActive;
// Constructors
public AppUser() {}
public AppUser(String fullName, Integer userAge, ZonedDateTime dateOfBirth, Boolean isActive) {
this.fullName = fullName;
this.userAge = userAge;
this.dateOfBirth = dateOfBirth;
this.isActive = isActive;
}
// Getters and Setters
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public Integer getUserAge() {
return userAge;
}
public void setUserAge(Integer userAge) {
this.userAge = userAge;
}
public ZonedDateTime getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(ZonedDateTime dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public Boolean getIsActive() {
return isActive;
}
public void setIsActive(Boolean isActive) {
this.isActive = isActive;
}
}
Explanation:
- @GeneratedValue(strategy = GenerationType.IDENTITY) indicates that the database will generate the primary key value automatically. Because of the IDENTITY strategy, each time a new AppUser is inserted, the database will create a unique value for userId.
- private Boolean isActive returns the value of whether the user is currently active. The value of this field is Boolean.
- A JPA entity that corresponds to the database's app_users table is the AppUser class.
Step 2: Derived Queries with Multiple Parameters
Next, you can utilize this query by passing the first name you wish to search for to the findByFirstName() method when you call an instance of the AuthorRepository.
Java
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@SpringBootTest(classes = MyApplication.class)
public class AuthorRepositoryTest {
@Autowired
private AuthorRepository authorRepo;
@Test
@Transactional
public void shouldFindAuthorsByFirstName() {
List<Author> authors = authorRepo.findByFirstName("Thorben");
// Add assertions or further actions to validate the result
}
}
Explanation:
- @SpringBootTest(classes = MyApplication.class, this annotation instructs Spring Boot to generate an application context for the test. The test may now execute in a fully initialized Spring environment thanks to it.
- @Autowired private AuthorRepository authorRepo inserts an instance of AuthorRepository into the test class with the command "AuthorRepository authorRepo;" This enables you to communicate with the database in your test using the repository ways.
Step 3: Define the Repository
Create a repository interface extending JpaRepository
to perform CRUD operations and custom queries:
Java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Find users by name and order them by name (default ordering, usually ascending)
List<User> findByNameOrderByName(String name);
// Find users by name and order them explicitly in ascending order
List<User> findByNameOrderByNameAsc(String name);
}
Explanation:
- public interface UserRepository extends JpaRepository<User, Long>, it comes to User entities—where User is the entity type and Long is the type of its main key—it permits both CRUD operations and additional custom queries.
- Sort the results according to the name field. If you use OrderByName without specifically setting the order, Spring Data JPA arranges the results in ascending order by default.
Step 4: Add Service Layer
We can build a service layer to communicate with the repository. This layer manages interactions between the controller and repository and may include business logic.
Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> getUsersByNameOrdered(String name) {
return userRepository.findByNameOrderByName(name);
}
public List<User> getUsersByNameOrderedAsc(String name) {
return userRepository.findByNameOrderByNameAsc(name);
}
}
Step 5: Use Controller Layer
Make a controller utilizing the service layer to process HTTP requests and return responses.
Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users/name/{name}")
public List<User> getUsersByNameOrdered(@PathVariable String name) {
return userService.getUsersByNameOrdered(name);
}
@GetMapping("/users/name/{name}/asc")
public List<User> getUsersByNameOrderedAsc(@PathVariable String name) {
return userService.getUsersByNameOrderedAsc(name);
}
}
Step 6: Compare the Records
Also, you may compare the records with the specified value using the \ and \= operators by utilizing the LessThan and LessThanEqual keywords.
Java
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface UserRepository extends JpaRepository<User, Integer> {
List<User> findUsersByAgeBelow(Integer age);
List<User> findUsersByAgeAtMost(Integer age);
}
Step 7: Limit the Number of Results
You can use Hibernate or any other JPA implementation to limit the number of returned records on the Query interface.
Java
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface CustomBookRepository extends JpaRepository<Book, Long> {
List<Book> findTop5ByTitleOrderByTitleAsc(String title);
}
Explanation:
- The JpaRepository interface from Spring Data JPA offers more query options for entities in addition to CRUD operations.
- An extension of the JpaRepository is the CustomBookRepository interface. This enables it to inherit the usual CRUD operations as well as extra query capabilities for Book entities, where the type of the entity is Long and the entity type is Book.
Step 8: Sorting and Paging
Lastly, you can add paging and sorting parameters to your methods.
Java
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
public interface UserRepository extends JpaRepository<User, Long> {
Page<User> findByAgeGreaterThan(int age, Pageable pageable);
}
Explanation:
- public interface UserRepository extends JpaRepository<User, Long>, describes the JpaRepository-extending UserRepository interface. JpaRepository is a Spring Data interface that offers additional features for entities in addition to the basic CRUD (Create, Read, Update, Delete) activities. In this case, the entity type is User, and the ID type of the entity is Long.
- You supply a Pageable object and an age value to the findByAgeGreaterThan function.
- To filter the User entities based on their age, utilize the age option.
- Page<User> findByAgeGreaterThan(int age, Pageable pageable), the repository interface defines this particular custom query method.
Conclusion
This article covers Derived Query Methods in Spring Data JPA Repositories with code and explanation, Spring Data JPA Repository is a Java Persistence API (Ja PA)-a specific extension of Repository. It includes the full APIs for CrudRepository and PagingAndSortingRepository. So it has APIs for basic CRUD activities, as well as pagination and sorting.
Similar Reads
findBy Methods in Spring Data JPA Repositories
Spring Data JPA abstracts the boilerplate code required to interact with the database, allowing developers to focus more on business logic rather than database connectivity and query formation. The findBy() method, in particular, is a part of the repository layer in Spring Data JPA, enabling develop
5 min read
Spring Data JPA - Delete Records From MySQL
Spring Boot simplifies database operations using Spring Data JPA, which provides built-in methods for CRUD (Create, Read, Update, Delete) operations. In modern application development, data manipulation is a critical task, and Java Persistence API (JPA) simplifies this process. Java persistence API
4 min read
JPA - Introduction to Query Methods
In Java, JPA can defined as Java Persistence API. It can provide a powerful and intuitive way to interact with the database using object-oriented paradigms. Query Methods Can offer a convenient approach to define database queries directly within the repository and it can reduce the boilerplate code
5 min read
Spring Security at Method Level
Spring Security provides a powerful way to secure Java applications, allowing developers to control authentication and access at different levels. One of its key features is method-level security, which lets us use security constraints on specific methods instead of the entire class or application.
2 min read
Spring Boot JPA Sample Maven Project With Query Methods
In this article, let us see a sample maven project in Spring Boot JPA with Query methods. Spring Boot + JPA removes the boilerplate code and it will be enhanced much if we use query methods as well. Let us discuss this project with MySQL Connectivity for geeksforgeeks database and table name as "Con
6 min read
CrudRepository, JpaRepository, and PagingAndSortingRepository in Spring Data
Spring Data JPA is a powerful tool in the Spring ecosystem that simplifies the implementation of data access layers in Java applications. It provides several repository interfaces, each offering different capabilities and levels of abstraction. These interfaces allow developers to perform operations
6 min read
Dynamic Query in Java Spring Boot with MongoDB
Most of todayâs applications require great flexibility regarding database querying. MongoDB provides an effective option for solving complex queries using this kind of storage for documents. Integrating it with Spring Boot makes things even smoother. In this article, we will look at how to create dy
4 min read
Show SQL from Spring Data JPA/Hibernate in Spring Boot
In Spring Boot, Spring Data JPA is part of the larger Spring Data Project that can simplify the development of the data access layers in the spring applications using the Java Persistence API and it can provide a higher-level abstraction over the JPA API. It can reduce the boilerplate code and make
6 min read
Spring Boot JpaRepository with Example
Spring Boot is built on the top of the spring and contains all the features of spring. And is becoming a favorite of developers these days because of its rapid production-ready environment which enables the developers to directly focus on the logic instead of struggling with the configuration and se
9 min read
Difference Between @RequestBody and @ResponseBody Annotation in Spring
To achieve the functionality of handling request data and response data in Spring MVC, @RequestBody and @ResponseBody annotations are used. So, in this article, we will go dive into the difference between @RequestBody and @ResponseBody annotations with an example. @RequestBody@RequestBody is mainly
3 min read