在 CriteriaBuilder 中使用多个参数

Working with multiple parameters in CriteriaBuilder

我需要使用 JpaSpecificationExecutor。 最初,我假设一个参数将作为输入给出,我会像这样处理它:

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);
    }

汽车资料库:

public interface CarRepository extends CrudRepository<Car, Long>, JpaSpecificationExecutor 

但是,我需要能够使用:

List<String> brands,
List<Integer> colors

作为对我的回应,出现了适合机器的所有选项。

例如输入:

brand = {honda, toyota},
color = {0x00ffff, 0x800000}

在输出中,我想获取所有属性属于以下条件之一的机器:

{honda,0x00ffff};{honda,0x800000};{toyota,0x00ffff};{toyota,0x800000}

我需要如何修改我的代码才能像我在示例中给出的那样工作?或者我在哪里可以读到它?

article 完美地解释了您的需求。

您基本上遍历 List<Brand>,创建品牌谓词列表,然后将此列表视为一个谓词块。

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);
}