如何将谓词列表添加到 CriteriaBuilder.or

How to add a list of Predicates to CriteriaBuilder.or

我有一个列表要附加到 or 条件中

我面临的问题是,当我遍历列表并将其添加到 CategoryBuilder 时,它需要最后一个 Predicate

示例如下:

public static Specification<Billoflading> hasTenantAndBillingCodeCombination(List<WhoOwnsIt> list,
            Date formattedFromDate, Date formattedToDate, String carrierFilter, String supplierFilter,
            String terminalFilter) {
        return (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            for (WhoOwnsIt whoOwnsIt : list) {
                String containsLikePatternForTenant = getContainsLikePattern(whoOwnsIt.getWholesalerTenantID(), true);

                Predicate pred = cb.and(cb.like(cb.lower(root.<String>get("tenant")), containsLikePatternForTenant),
                        cb.equal(cb.lower(root.<String>get("billingCode")), whoOwnsIt.getBillingCode()),
                        cb.greaterThanOrEqualTo(root.<Date>get("scheduleDate"), formattedFromDate),
                        cb.lessThanOrEqualTo(root.<Date>get("scheduleDate"), formattedToDate));

                Predicate predWithTenant = null;

                if (null != carrierFilter) {
                    predWithTenant = cb.and(cb.equal(cb.lower(root.<String>get("tenant")), carrierFilter));
                }

                if (null != predWithTenant)
                    predicates.add(predWithTenant);
                else
                    predicates.add(pred);

            }
            Predicate finalPredicate;
            // This commented section below needs to be replaced with a 
            //better solution
            //for(Predicate predicate : predicates){
            //  cb.or(predicate);
            //}

            return finalPredicate;
        };
    }

我还尝试使列表成为一个数组,以便将其传递给 finalPredicate.or,如下所示

Predicate finalQuery = cb.or(predicates.toArray());

但是这段代码给出了编译错误,因为需要的参数是可变参数 即

或方法接受(谓词...谓词)作为参数列表

你能提供一些简单的解决方案吗?

试试这个:

Predicate finalQuery = cb.or(predicates.toArray(new Predicate[0]));

作为补充,我建议对较新的 Java 版本使用以下表示法:

builder.or(predicates.toArray(Predicate[]::new))

我写的示例代码可能会有帮助,这里将所有谓词收集到一个列表中,然后将列表转换为数组,该数组将被构建器使用。

 public List< EntityClass> getData(List<Long> ids) {

    List<List<Long>> idPartitions = ListUtils.partition(ids, 999);
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<EntityClass> criteria = builder.createQuery(EntityClass.class);

    Root<EntityClass> root = criteria.from(EntityClass.class);

    List<Predicate> predicates = new ArrayList<>(idPartitions.size());
    for (List<Long> idPartition : idPartitions) {
      predicates.add(root.get("id").in(idPartition));
    }

    criteria.where(builder.and(predicates.toArray(new Predicate[0])));
    List<EntityClass> objects = entityManager.createQuery(criteria).getResultList();
    return objects;
  }