Home > Back-end >  How to have filtering of multiple parameters passed as RequestParams in Spring Data Jpa?
How to have filtering of multiple parameters passed as RequestParams in Spring Data Jpa?

Time:10-24

Suppose I have an Employee class with multiple fields like name, age, salary, designation, joiningDate, gender and many more. Now, how could I apply filtering with many such parameters? There could be many combinations possible in such cases. (For Eg. if I want to have 6 filters, then there can be total of 6! = 720 combinations possible!!!)

For only 2,3 parameters, like age, salary, name; then I could write multiple if cases like:

if(age!=null && name==null && salary==null)
{
    findByAge
}
if(age==null && name!=null && salary==null)
{
    findByName
}
if(age!=null && name!=null && salary==null)
{
    findByAgeAndName
}

etc. like these with help of Spring Data JPA. But how to handle more parameters since combinations would increase with each RequestParams?

CodePudding user response:

What you are looking for is a multi criteria query. You can use the very simple Example API

In your case, the code sould look something like this :

You will create an entity with the builder pattern. Lombok can help you in this step :

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "employee")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "name")
    private String name;
    @Column(name = "age")
    private int age;
    // your other fields

}

Then you can call your method :

Employee employee = Employee
    .builder()
    .name(nameValue)
    .age(ageValue)
    .build();

return repository.findAll(Example.of(employee));

You will find a full example here.

CodePudding user response:

You should not write many condition and/or to call the function. It's hard to combine many condition.

In this case i often write the query which will append the condition if parameter is not null or if specify.

Here is my way:

String query = "select * from table where 1=1";
Map<String,Object> params = new HashMap<>();
if(filter1!=null){
   query  = " and field1 = :filter1";
   params.put("filter1",filter1);
}
if(filter2!=null){
   query  = " and field2 = :filter2";
   params.put("filter2",filter2);
}
dao.execute(query,params);

The condition null is not required, you can adapt it. In case you don't want to have many arguments in your function. You can create object/context/map to hold all filters.

PS: I use String for readability, you should use StringBuilder.

For spring-jpa: ExampleMatcher can do the same.

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#query-by-example.matchers

CodePudding user response:

A solution is to have a single method, and make parameters "optional" by managing null values in the query :

@Query("""
       select a from YourEntity a where
       (?1 is null or a.name = ?1)
       and (?2 is null or a.age= ?2)
       and (?3 is null or a.salary = ?3)
       and (?4 is null or a.description = ?4)
       and (?5 is null or a.joiningDate = ?5)
       and (?6 is null or a.gender = ?6)
       """)
List<YourEntity> findFiltered(String name, Integer age, Float salary, String designation, LocalDateTime joiningDate, String gender)
  • Related