I'm trying to use @RequestParam, and if the value is given it should filter from all items found in the database by this parameter, if not it should do nothing. I would also like to ask if functional programming is a good use here.
This is my Car class:
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;
}
}
This is the Controller where I set the parameters to ask for:
@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);
}
This is Car Service and what I would like to do:
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());
}
I could set @RequestParam (defaultValue = "something")
in controller, but it's problematic since I don't know what are the default values for "model" field, because every Car has a different model, and still I have to filter items by default values, and it's not needed since I don't want to do anything with that if it's not given.
I was also trying to pass Optional<>
as the parameters and then check every parameter with if statement and ifPresent() method in filter function, but I don't how how to bring it together.
CodePudding user response:
You can create a jpa query like this (in your car repository):
@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);
and then call it from your CarService
:
public List<Car> getCars(Integer minPrice, Integer maxPrice, String model) {
return carRepository.getCars(minPrice, maxPrice, model);
}
One way to circumvent cast problem in postgresql, is to use default values for the params. Say you set 0 as default value for min price and max price and empty string for model.
@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);
And in your controller:
@RequestParam(defaultValue="") String model
@RequestParam(defaultValue="0") Integer minPrice
@RequestParam(defaultValue="0") Integer maxPrice