如果给定@RequestParameter,则按其值过滤,如果没有,则不执行任何操作[重复]

Posted

技术标签:

【中文标题】如果给定@RequestParameter,则按其值过滤,如果没有,则不执行任何操作[重复]【英文标题】:If @RequestParameter is given, filter by it's value, if not do nothing [duplicate] 【发布时间】:2021-12-20 03:32:40 【问题描述】:

我正在尝试使用@RequestParam,如果给定了值,它应该通过这个参数从数据库中找到的所有项目中过滤,如果没有,它应该什么都不做。我还想问一下函数式编程在这里是否很好用。

这是我的汽车课:

import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;

import javax.persistence.*;

@Data
@Entity
@Table(name = "Cars")
public class Car 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Setter(AccessLevel.NONE)
    private Long Id;

    private int yearOfProduction;
    private int price;
    private String color;
    private String brand;
    private String model;

    @ManyToOne
    @JoinColumn(name = "customer")
    private Customer customer;

    public Car() 
    

    public Car(int yearOfProduction, int price, String color, String brand, String model) 
        this.yearOfProduction = yearOfProduction;
        this.price = price;
        this.color = color;
        this.brand = brand;
        this.model = model;
    

这是我设置要请求的参数的控制器:

@GetMapping
public List<Car> getCars(@RequestParam(required = false) Integer minPrice,
                         @RequestParam(required = false) Integer maxPrice,
                         @RequestParam(required = false) String model)

    return carService.getCars(minPrice, maxPrice, model);

这是汽车服务,我想做的事:

public List<Car> getCars(Integer minPrice, Integer maxPrice, String model) 
    return carRepository
            .findAll()
            .stream()
            .filter(car ->
                      //if minPrice exists
                                car.getPrice() >= minPrice
                                 &&
                       //if maxPrice exists
                                 car.getPrice() <= maxPrice
                                 &&
                       //if model exists
                                 car.getModel().equals(model))
                      .collect(Collectors.toList());

我可以在控制器中设置@RequestParam (defaultValue = "something"),但这是有问题的,因为我不知道“模型”字段的默认值是什么,因为每辆汽车都有不同的模型,我仍然必须按默认值过滤项目,并且它不是必需的,因为如果没有给出它,我不想对它做任何事情。

我还尝试将Optional&lt;&gt; 作为参数传递,然后在过滤函数中使用 if 语句和 ifPresent() 方法检查每个参数,但我不知道如何将它们组合在一起。

【问题讨论】:

一个简单的规则要遵循,不要在你的代码中做任何事情,数据库比你做得更好。过滤和排序由数据库更好地处理。 @b.GHILAS 因此,您建议在存储库中创建例如 3 个 SQL 查询,然后在 getCars() 函数中编写 3 个 if 语句,检查参数是否存在并在其中执行正确的函数?因为我不知道如何使给定参数的所有配置在这些查询中起作用,因为其中一些肯定具有共同的元素。请您详细解释一下吗? 更新您的问题并提供实体 Car,我假设您希望默认获取所有汽车,并且如果有任何请求参数过滤器。如果这是您想要的,那么使用 JPA 很容易实现。 @b.GHILAS 我更新了它,是的,这正是我想要做的。 @b.GHILAS 是正确的。不要获取服务中的所有值和过滤器。将默认值设置为 * 并将值传递给您的 @Repository 以用于参数化查询(以避免 SQL 注入攻击)。 【参考方案1】:

您可以像这样创建一个 jpa 查询(在您的汽车存储库中):

@Query("select c from Car c where (?1 is null or c.price >= ?1) and (?2 is null or c.price <= ?2) and (?3 is null or c.model = ?3)")
List<Car> getCars(Integer minPrice, Integer maxPrice, String model);

然后从您的CarService 调用它:

public List<Car> getCars(Integer minPrice, Integer maxPrice, String model) 
   return carRepository.getCars(minPrice, maxPrice, model);


在 postgresql 中规避强制转换问题的一种方法是使用参数的默认值。假设您将 0 设置为最低价格和最高价格的默认值以及模型的空字符串。

@Query("select c from Car c where (?1 = 0 or c.price >= ?1) and (?2 = 0 or c.price <= ?2) and (?3 = '' or c.model = ?3)")
List<Car> getCars(Integer minPrice, Integer maxPrice, String model);

在你的控制器中:

@RequestParam(defaultValue="") String model
@RequestParam(defaultValue="0") Integer minPrice
@RequestParam(defaultValue="0") Integer maxPrice

【讨论】:

不幸的是,我收到错误:,,ERROR: 运算符不存在:整数 >= bytea 提示:没有运算符与给定的名称和参数类型匹配。您可能需要添加显式类型转换。” @77jt777 更新了答案 它现在工作正常,它没有显示错误,但是当我发送请求时它返回响应代码 200 但我没有得到任何结果(没有显示任何汽车) @77jt777 默认值配置好了吗,生成的查询是什么? 这是我在控制台中唯一得到的:休眠:选择 car0_.id 作为 id1_0_,car0_.brand 作为brand2_0_,car0_.color 作为 color3_0_,car0_.customer 作为 customer7_0_,car0_.model 作为 model4_0_ , car0_.price as price5_0_, car0_.year_of_production as year_of_6_0_ from cars car0_ where (?=0 or car0_.price>=?) and (?=0 or car0_.price

以上是关于如果给定@RequestParameter,则按其值过滤,如果没有,则不执行任何操作[重复]的主要内容,如果未能解决你的问题,请参考以下文章

按其rowname和columnname访问值,而不是数字

Java按整数字段对对象数组进行排序,如果它们相同,则按另一个整数值排序

python 排序 sorted 如果第一个条件 相同 则按第二个条件排序

compactMapValues不过滤零值

获得列表中重复次数最多的名称,如果出现平局,则按字母顺序排列第一个

bash的常见特性及文本查看命令