简体   繁体   English

如何在 Spring Data Jpa 中过滤作为 RequestParams 传递的多个参数?

[英]How to have filtering of multiple parameters passed as RequestParams in Spring Data Jpa?

Suppose I have an Employee class with multiple fields like name, age, salary, designation, joiningDate, gender and many more.假设我有一个 Employee 类,其中包含多个字段,如姓名、年龄、薪水、职位、加入日期、性别等等。 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!!!) (例如,如果我想要 6 个过滤器,那么总共可以有 6 个!= 720 种可能的组合!!!)

For only 2,3 parameters, like age, salary, name;仅适用于 2,3 个参数,如年龄、薪水、姓名; then I could write multiple if cases like:那么我可以写多个 if 案例:

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.等等,像这些在 Spring Data JPA 的帮助下。 But how to handle more parameters since combinations would increase with each RequestParams?但是如何处理更多的参数,因为每个 RequestParams 的组合都会增加?

What you are looking for is a multi criteria query.您正在寻找的是多条件查询。 You can use the very simple Example API您可以使用非常简单的示例 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 : Lombok 可以帮助您完成这一步:

@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 .你会 在这里找到一个完整的例子。

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.条件 null 不是必需的,您可以对其进行调整。 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. PS:我使用 String 来提高可读性,你应该使用 StringBuilder。

For spring-jpa: ExampleMatcher can do the same.对于 spring-jpa:ExampleMatcher 可以做同样的事情。

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

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM