Sunday, April 5, 2020

Spring Data JPA : Query by Example

Spring Data JPA : Query by Example(QBE)




If you are a java developer and if anyone asks to you to create an enterprise application, suddenly your head will move left & right around the JAVA orbit and Spring/Spring Boot framework will hit your brain. Of course others might be, but it is often. Am i right ?

Spring Boot  ecosystem is an evolution of Spring framework which helps to create stand-alone, production-grade Spring based applications with minimal effort.

Lucky-draw Coupons 


In a festival time, my manager asked me to implement the following use case .
  1.  You have to find all the customers whose first name ends with some given character and to send some random lucky draw coupon code which they can redeem on a e-commerce site. 
Yes, i can use native DB query ; but he doesn't give green signal !!! for db query, because later he has to do some intermediate operations too and he ordered me to achieve it using spring boot . 

You might also be interested in the related tutorials:

Spring Data JPA

It facilitates the implementation of JPA based repositories. It makes the life easier to build spring based applications that uses data access technologies.

Spring Data JPA Query By Example

If you are using Spring Data JPA, you might have used JpaRepository of spring data JPA. If you check the JpaRepository.class you will find the below signature :

public interface JpaRepository<T, ID>
  extends PagingAndSortingRepository<T, ID>,
QueryByExampleExecutor<T> {}

See, it extends QueryByExampleExecutor .So what is this and why it has extended ?

Query By Example(QBE) is a developer-friendly querying technique which facilitates to write dynamic query without any specific query-language.

It allows us to execute queries based on an Example entity instance. The field of the Example instance needs to be populated with the desired criteria values. 

In Spring Data JPA we can use org.springframework.data.domain.Example instance which takes an entity instance (called 'probe' in this context). E.g
//get all the customers whose first name is ending with 'dra' 
var customers = Customers.builder().firstName(ending).build();
 var matcher = ExampleMatcher.matching()
.withIgnoreNullValues()
.withMatcher("firstName", match ->                  match.endsWith().ignoreCase(true));
 var example = Example.of(customers, matcher);

By default, fields having null values are ignored in the underlying query, so above Example will be equivalent to the following JPQL:
SELECT t from Customer c where c.firstName = '%dra';

Examples

I am going to implement the same above mentioned use case.
1. Get All customers
2. Get all customers whose first name ends with 'dra'
3. Get all customers whose last name ends with 'das'
4. Get all customers whose first name equals 'Rosalin'
5. Get all customers whose wallet balance is 2000
Let's start with a simple example:

Entity : Customer.java


@Entity
@Table(name = "customers")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
@Builder
public class Customers implements Serializable{
private static final long serialVersionUID = 34131213L;
@Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
@Column(name = "first_name", nullable = false)
    private String firstName;
@Column(name = "last_name")
    private String lastName;
@Column(name = "balance")
private Long   walletBalance;
}

Service : CustomerService.java

public List<Customers> findByFirstNameEnding(String ending) {
var customers = Customers.builder().firstName(ending).build();
var matcher = ExampleMatcher.matching()
.withIgnoreNullValues()
.withMatcher("firstName", match -> match.endsWith().ignoreCase(true));
var example = Example.of(customers, matcher);
return (List<Customers>) customerRepository.findAll(example);
}

Find the complete code on github.



In this tutorial, we have used Spring Data JPA Query By Example technique to generate queries. You might also be interested in the related tutorials:

No comments:

Post a Comment