在 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);
}
我需要使用 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);
}