QueryDSL使用OR运算符而不是AND

时间:2017-11-17 08:41:14

标签: java spring rest predicate querydsl

我需要一些QueryDSL lib的帮助。更具体地说,我有这个:

我正在尝试创建一个搜索端点,使用户能够搜索具有特定功能的已保存项目,例如名称,位置,所有者等。(可搜索的字段是类变量)

@GetMapping(value = "/search", produces = MediaTypes.HAL_JSON_VALUE)
PagedResources<SavedItemResource> searchByQuery(final Pageable pageable,
                                                    @RequestParam(value = "type", required = false) final List<String> typeFilters,
                                                    @QuerydslPredicate(root = SavedItem.class) Predicate predicate) {
   return pagedResourcesAssembler.toResource(service.findAll(predicate,pageable), assembler);
}

我自定义了这样的绑定,以支持每个字段的值列表。

 MultiValueBinding<StringPath, String> contains = (path, values) -> {
        BooleanBuilder predicate = new BooleanBuilder();
        for (String value : values) {
            predicate.or(path.containsIgnoreCase(value));
        }
        return predicate;
    };

如果我只搜索一个字段,这非常有效。但是当我在多个字段上搜索时,它不起作用,因为@QuerydslPredicate将使用AND运算符生成谓词。但我需要在不同领域之间进行OR。

有一种简单的方法吗? Thx提前!

1 个答案:

答案 0 :(得分:0)

您可以尝试使用此方法来创建一个新的谓词,以替换OR的AND运算符:

public static Predicate replaceAndForOR(Predicate predicate) {
if (predicate instanceof PredicateOperation) {
  PredicateOperation operation = (PredicateOperation) predicate;
  List<Expression<?>> expressions = operation.getArgs();
  BooleanBuilder builder = new BooleanBuilder();

  for (Expression<?> exp : expressions) {
    String[] expStrings = exp.toString().split("&&");
    PredicateOperation op = (PredicateOperation) exp;

    if (expStrings.length > 1) {
      Predicate p = replaceAndForOR(op);
      builder.or(p);
    } else {
      builder.or(op);
    }
  }

  return builder.getValue();
} else {
  return predicate;
}

}