我有一个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 ?
还是我必须创建一个自定义控制器和/或存储库方法?
答案 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