By Default JPARepositories interface will provide some predefined method such as save(), findAll(), findById(), and findOne etc.. In case if we need to load data based on other property using emailAddress or phoneNumber etc, then we need to create our own user defined findXXX() methods in the repository like findByEmailAddress(), findByMobileNumber(), findByFirstName(), etc..
Keyword | Sample | JPQL snippet |
---|---|---|
Distinct | findDistinctByLastnameAndFirstname | select distinct … where x.lastname = ?1 and x.firstname = ?2 |
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is, Equals | findByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull, Null | findByAge(Is)Null | … where x.age is null |
IsNotNull, NotNull | findByAge(Is)NotNull | … where x.age is not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection<Age> ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection |
… where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstname) = UPPER(?1) |
First, we need to create a simple SprintBoot and SprintDataJPA applicaiton using MySql, which can be created with the help of following tutorial Customer Registration on top of this we need to make changes to implement a query by method name concept
First will introduce a new enpoint in controller to load data based on the emailAddress like below:
/**
* fetch data based on the emailAddress, using QueryByMethod name concept.
*
* @param emailAddress customer email address
* @return response entity object
*/
@GetMapping("/getByEmail/{emailAddress}")
public ResponseEntity<APIResponse> getCustomerByEmail(@PathVariable String emailAddress) {
return customerService.getCustomerByEmail(emailAddress);
}
Introduce new method in service and service Implementation class so that we can call the user defined query method from repository
ResponseEntity<APIResponse> getCustomerByEmail(String emailAddress);
Service Implementation class
/**
* This method is used to call the user defined Query method from repository.
*
* @param emailAddress customer email address
* @return responseEntity object
*/
@Override
public ResponseEntity<APIResponse> getCustomerByEmail(String emailAddress) {
Optional<CustomerModel> optional = customerRepository.findByCustomerEmailAddress(emailAddress);
if (!optional.isPresent()) {
return ResponseEntity.ok(
APIResponse.builder()
.errorCode(CUSTOMER_EMAIL_NOT_EXISTS_CODE)
.errorMessage(CUSTOMER_EMAIL_NOT_EXISTS)
.data(List.of())
.build()
);
}
CustomerModel model = optional.get();
CustomerResponse response = modelToResponseMapper(model);
return ResponseEntity.ok(
APIResponse.builder()
.errorCode(SUCCESS_CODE)
.errorMessage(SUCCESSFULLY_RETRIEVED)
.data(response)
.build()
);
}
Add new error code and error message in APPConstants.java file
public static final Integer CUSTOMER_EMAIL_NOT_EXISTS_CODE = 901;
public static final String CUSTOMER_EMAIL_NOT_EXISTS = "Customer email address not exists";
To implement a PATCH HTTP request, first we need to create a new enpoint in controller like below.
/**
* update a specific field from the entity, using PATCH
*
* @param customerId customer id
* @param customerAddress customer address object
* @return response entity object
*/
@PatchMapping("/update/address/{customerId}")
public ResponseEntity<APIResponse> updateAddress(@PathVariable long customerId, @RequestBody CustomerAddress customerAddress) {
return customerService.updateCustomerAddress(customerId, customerAddress);
}
Add user defined method CustomerRepository interface, like below
package com.sb.sdjpa.crud.repository;
import com.sb.sdjpa.crud.model.CustomerModel;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface CustomerRepository extends JpaRepository {
Optional<CustomerModel> findByCustomerEmailAddress(String emailAddress);
}
By using this http://localhost:8090/api/v1/customer/getByEmail/{emailAddress} endpoint we can make a request to load the data based on the emailAddress.
If we pass invalid email address, which is not registered with system then will receive a message call Customer email address not exists
Full source code is available in follwong GitHub repository: SpringBoot Query By Method Name