多个路径之间的QueryDSL谓词绑定“或”

时间:2019-04-17 08:23:56

标签: java spring-boot spring-data spring-data-mongodb querydsl

我有一个Spring Boot Rest API来使用 Querydsl 谓词进行过滤,我在 MongoRepository 上使用 QuerydslBinderCustomizer 将属性路径绑定到自定义查询。

为同一路径设置多个搜索值时的默认行为是这些值之间的OR运算符。

但是当使用多路径并且使用AND运算符时。

我想做的是在多个所选路径之间放置一个OR运算符。

我找到了这个非常清晰的文档,但没有找到答案:https://gt-tech.bitbucket.io/spring-data-querydsl-value-operators/README.html

今天我有:

控制器

public Page<Document> find(
            @QuerydslPredicate(root = Document.class) Predicate predicate) {
        return repository.findAll(predicate);
    }

库存

public interface Repository extends
        MongoRepository<Document, String>,
        QueryDslPredicateExecutor<EventRuleDocument>,
        QuerydslBinderCustomizer<QEventRuleDocument> {

    @Override
    default void customize(QuerydslBindings bindings, QDocument doc) {
        bindings.bind(doc.prop1).first(StringExpression::containsIgnoreCase);
        bindings.bind(doc.prop2).first(StringExpression::containsIgnoreCase);
        bindings.bind(doc.prop3).first(StringExpression::containsIgnoreCase);
    }
}

女巫给了我谓词:prop1 == v1 AND prop2 == v2 AND prop3 == v3

我想要实现的是:prop1 == v1 OR prop2 == v2 OR prop3 == v3

是否可以使用 QuerydslBinderCustomizer

还是我必须创建一个自定义控制器和/或存储库方法?

1 个答案:

答案 0 :(得分:1)

@Override
default void customize(QuerydslBindings bindings, QDocument root) {

StringPath[] multiPropertySearchPaths = new StringPath[] {root.prop1, root.prop2, root.prop3};

/**
 * Binds prop1, prop2 and prop3 in OR clause
 * This binding will activate when one of the given properties are searched in query params
 */
bindings.bind(multiPropertySearchPaths).all(new MultiValueBinding<StringPath, String>() {
    @Override
    public Predicate bind(StringPath path, Collection<? extends String> values) {
        BooleanBuilder predicate = new BooleanBuilder();
        // Bind paths present in array multiPropertySearchPaths with incoming values
        for (StringPath propertyPath : multiPropertySearchPaths) {
            values.forEach(value -> predicate.or(propertyPath.containsIgnoreCase(value)));
        }
        return predicate;
    }
});
}

它将生成类似sql的

select * from document
where
    lower(document.prop1) like ?1 
    or lower(document.prop2) like ?1 
    or lower(document.prop3) like ?1