假设我有一个Employee
类,具有多个字段,如name
,age
,salary
,designation
,joiningDate
,gender
等等。现在,我如何应用有很多这样的参数的过滤呢?在这种情况下,可能有许多可能的组合。(如。如果我想有6个过滤器,那么总共可以有6个!= 720种可能的组合!!)
仅适用于2,3个参数,如age
,salary
,name
;那么我可以写多个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
}
等。在Spring Data JPA的帮助下。但是如何处理更多的参数,因为组合会随着每个RequestParams的增加而增加?
您要查找的是一个多条件查询。您可以使用非常简单的示例API
您将使用构建器模式创建一个实体。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
}
然后你可以调用你的方法:
Employee employee = Employee
.builder()
.name(nameValue)
.age(ageValue)
.build();
return repository.findAll(Example.of(employee));
你可以在这里找到一个完整的例子。
解决方案是使用单一方法,并使参数"可选";通过管理查询中的空值:
@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)
您不应该编写许多条件和/或调用函数。很难把许多条件结合起来。
在这种情况下,我经常写查询,如果参数不为空或指定,则附加条件。
这是我的方法:
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);
null条件不是必需的,您可以调整它。以防你不想在函数中有很多参数。你可以创建object/context/map来保存所有的过滤器。
PS:我使用String是为了可读性,你应该使用StringBuilder。
spring-jpa:ExampleMatcher也可以这样做。
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/query-by-example.matchers