带有Query Dsl自定义绑定的Spring和/或操作不起作用

Emr*_*ürk 5 java binding spring filter querydsl

我有以下需求查询:

“ /文章?类别 =厨房和类别 =体育”

此查询无需自定义绑定即可运行。它将给我所有关于厨房和体育的文章作为回应。它正在以某种方式进行“或”操作。

但是我需要自定义绑定,因为我需要阅读案例。现在我正在使用此自定义绑定:

@Repository
public interface ArticleRepository extends JpaRepository<Article, Long>, 
QueryDslPredicateExecutor<QArticle>, QuerydslBinderCustomizer<QArticle> {


 @Override
  default public void customize(QuerydslBindings bindings, QArticle article) {

     bindings.bind(String.class).first((StringPath path, String value) -> path.containsIgnoreCase(value));
  }
}
Run Code Online (Sandbox Code Playgroud)

这只会过滤属性的第一个可用值。因此,在这种情况下,它仅将类别Kitchen中的文章作为Response。类别(运动)的第二个值将被忽略。

现在,我的问题是:我如何才能忽略这两个类别的文章而忽略大小写?我需要在自定义绑定中进行哪些更改才能实现?

非常感谢你

Mar*_*rin 5

QuerydslBindings.TypeBinder#first 使用单值绑定。您需要使用 QuerydslBindings.TypeBinder# all。此方法对 多值绑定进行操作

我在此答案中提供了几个有关如何自定义绑定的示例。这样的事情应该适合你:

@Override
default public void customize(QuerydslBindings bindings, QArticle article) {
    // using explicit path bindings
    bindings.bind(article.category).all((path, values) -> {
        BooleanBuilder predicate = new BooleanBuilder();
        // with a for loop
        for (String value : values) {
            predicate.or(path.containsIgnoreCase(value));
        }
    });

    // using a type binding
    bindings.bind(String.class).all((StringPath path, Collection<? extends String> values) -> {
        BooleanBuilder predicate = new BooleanBuilder();
        // oneliner with Java 8 forEach
        values.forEach( value -> predicate.or(path.containsIgnoreCase(value) );
    });

}
Run Code Online (Sandbox Code Playgroud)


小智 5

经过一番仔细搜索后,我找到了解决方案。

 bindings.bind(String.class).all(new MultiValueBinding<StringPath, String> () {
        @Override
        public Predicate bind(StringPath path, Collection<? extends String> values) {
            BooleanBuilder predicate = new BooleanBuilder();
            values.forEach( value -> predicate.or(path.containsIgnoreCase(value)));
            return predicate;
        }
    });
Run Code Online (Sandbox Code Playgroud)


Ada*_*zek 5

您的article.category财产的正确绑定应该是这样的:

bindings.bind(article.category).all((path, value) -> {
    BooleanBuilder predicate = new BooleanBuilder();
    value.forEach(o -> predicate.or(path.equalsIgnoreCase(o)));
    return Optional.of(predicate);
});
Run Code Online (Sandbox Code Playgroud)

如果您不需要对参数进行任何操作(例如忽略大小写),您可以将其简化为:

bindings.bind(article.category).all((path, value) -> Optional.of(path.in(value)));
Run Code Online (Sandbox Code Playgroud)