I have a need to use JpaSpecificationExecutor. Initially, I assumed that one parameter would be given as input and I would process it like this:
List<Car> findCarsByParameters( String brand, Integer color ) { Specification<Car> querySpec = new Specification<Car>() { @Override public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) { List<Predicate> predicates = new ArrayList<>(); if (!brand.isEmpty()) { predicates.add(criteriaBuilder.like(root.get("brand"), brand)); } if (color != null) { predicates.add(criteriaBuilder.equal(root.get("color"), color)); } return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); } }; return carRepository.findAll(querySpec); }
CarRepository :
public interface CarRepository extends CrudRepository<Car, Long>, JpaSpecificationExecutor
However, I need to be able to work with:
List<String> brands, List<Integer> colors
And in response to me came all the options for suitable machines.
For example input:
brand = {honda, toyota}, color = {0x00ffff, 0x800000}
At the output, I want to get all the machines whose properties fall under one of the following conditions:
{honda,0x00ffff};{honda,0x800000};{toyota,0x00ffff};{toyota,0x800000}
How do I need to modify my code so that it works like I gave in the example? Or where can I read about it?
Advertisement
Answer
This article perfectly explains what you need.
You basically iterate through the List<Brand>
, create a list of brand predicates then consider this list as one block of predicate.
List<Car> findCarsByParameters( List<String> brands, List<Integer> colors ) { Specification<Car> querySpec = new Specification<Car>() { @Override public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) { List<Predicate> brandPredicates = new ArrayList<>(); if (brands != null && !brand.isEmpty()) { brandPredicates = brands.stream() .map((brand) -> criteriaBuilder.like(root.get("brand"), brand)) .collect(Collectors.toList()); } Predicate predicateForBrand = criteriaBuilder.or(brandPredicates.toArray(Predicate[]::new)); List<Predicate> colorPredicates = new ArrayList<>(); if (colors != null && !colors.isEmpty()) { colorPredicates = colors.stream() .map((color) -> criteriaBuilder.like(root.get("color"), color)) .collect(Collectors.toList()); } Predicated predicateForColor = criteriaBuilder.or(colorPredicates.toArray(Predicate[]::new)); return criteriaBuilder.and(predicateForColor, predicateForBrand); } }; return carRepository.findAll(querySpec); }