QueryDSL 谓词绑定“或"多条路径之间 [英] QueryDSL predicate bindings "or" between multiple path

查看:43
本文介绍了QueryDSL 谓词绑定“或"多条路径之间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Spring boot Rest API 女巫使用 Querydsl 谓词进行过滤,我使用 MongoRepository 上的 QuerydslBinderCustomizer 将属性路径绑定到自定义查询.

I have a Spring boot Rest API witch use Querydsl predicate for filtering, I use the QuerydslBinderCustomizer on my MongoRepository to bind properties path to customize the query.

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

The default behavior when multiple search values are set for the same path is an OR operator between these values.

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

But when multiple path are used and AND operator is used.

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

What I want to do is to put an OR operator between multiple chosen path.

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

I found this quite clear documentation but didin't find an answer in it : 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);
    }
}

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

Witch gives me the predicate : prop1 == v1 AND prop2 == v2 AND prop3 == v3

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

这可以使用 QuerydslBinderCustomizer 吗?

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

Or do I have to create a custom controller and/or repository method ?

推荐答案

@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:

It will generate sql like:

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

这篇关于QueryDSL 谓词绑定“或"多条路径之间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆