Spring Boot可选@RequestParam动态过滤查询结果及函数式编程适用性咨询
问题解答
动态过滤代码实现
你要的逻辑可以直接通过在filter条件中增加空值判断实现,空参数对应的条件直接返回true(即不做该维度过滤),参考代码如下:
import java.util.Objects; import java.util.stream.Collectors; public List<Car> getCars(Integer minPrice, Integer maxPrice, String model) { return carRepository .findAll() .stream() .filter(car -> // minPrice为空就跳过该条件,否则判断价格大于等于最小值 (minPrice == null || car.getPrice() >= minPrice) && // maxPrice为空就跳过该条件,否则判断价格小于等于最大值 (maxPrice == null || car.getPrice() <= maxPrice) && // model为空就跳过该条件,否则判断型号匹配,用Objects.equals避免空指针 (model == null || Objects.equals(car.getModel(), model)) ) .collect(Collectors.toList()); }
如果要更符合函数式编程风格、方便后续扩展过滤维度,可以把每个过滤规则抽成独立的Predicate<Car>,再组合使用:
public List<Car> getCars(Integer minPrice, Integer maxPrice, String model) { // 每个过滤维度独立定义,新增规则只需要加对应Predicate即可 Predicate<Car> minPriceFilter = car -> minPrice == null || car.getPrice() >= minPrice; Predicate<Car> maxPriceFilter = car -> maxPrice == null || car.getPrice() <= maxPrice; Predicate<Car> modelFilter = car -> model == null || Objects.equals(car.getModel(), model); return carRepository .findAll() .stream() // 组合所有过滤规则 .filter(minPriceFilter.and(maxPriceFilter).and(modelFilter)) .collect(Collectors.toList()); }
该场景是否适合函数式编程
完全适合,优势非常明显:
- 逻辑可读性高,声明式的写法可以直观对应每个过滤规则,不需要写大量嵌套的if判断
- 扩展性强,后续要加生产年份、品牌、颜色等过滤维度,只需要新增独立的Predicate即可,不需要修改原有过滤逻辑
- 组合灵活,多个过滤条件可以通过
and()/or()任意组合,适配复杂的过滤需求 - 无副作用,所有过滤逻辑只做判断不修改数据,完全符合函数式编程的特性
性能优化提示
如果你的车辆数据量较大,不建议查询全表后在内存做过滤,推荐用JPA Specification或者QueryDSL实现数据库层面的动态查询,减少IO开销。
内容的提问来源于stack exchange,提问作者77jt777
相关产品推荐
相关产品推荐

