[英]Spring - Advanced comparator for QueryDsl support
Following the official documentation , adding @EnableSpringDataWebSupport
annotation to my Spring configuration allows to automatically inject a Predicate
class in query: 遵循官方文档 ,在我的Spring配置中添加@EnableSpringDataWebSupport
批注允许在查询中自动注入Predicate
类:
@RequestMapping(method = RequestMethod.GET, path="/find")
public ResponseEntity<PagedResources<FooResource>> find(Pageable pageable, PagedResourcesAssembler<Foo> assembler, @QuerydslPredicate(root = Foo.class) Predicate predicate) {
Page<Foo> foos = fooRepository.findAll(predicate, pageable)
final ResourceAssemblerSupport<Foo, FooResource> fooResourceAssembler = new ....;
final PagedResources<FooResource> pagedResources = assembler.toResource(foos, fooResourceAssembler);
return new ResponseEntity<>(pagedResources, HttpStatus.OK);
}
Then I can easily search when performing the GET request: 然后,我可以在执行GET请求时轻松搜索:
GET /foo/name?=bob&name=alice&age=20
This works fine. 这很好。 However I was wondering how to achieve more advanced search criteria: 但是我想知道如何实现更高级的搜索条件:
>
<
>=
<=
Typically I would like to apply these operators to numeric and date fields in my data models. 通常,我想将这些运算符应用于数据模型中的数字和日期字段。 These sorts of criterion are supported in Querydsl. Querydsl支持这些类型的条件。
I tried adding > (%3E)
in my query parameters but it fails parsing (for example for numeric field like age it complains it cannot parse >10
as a number. 我尝试在查询参数中添加> (%3E)
,但解析失败(例如,对于年龄这样的数字字段,它抱怨无法将>10
解析为数字。
Is it possible to use this operator directly in the query? 是否可以在查询中直接使用此运算符?
(In case it matters I'm using Spring Data Mongodb) (以防万一,我正在使用Spring Data Mongodb)
Custom Query DSL binding - greater than comparison 自定义查询DSL绑定-大于比较
What you can do is define your own QueryDSL Binding in your repository, by extending QueryDslPredicateExecutor
and QuerydslBinderCustomizer
: 您可以做的是通过扩展QueryDslPredicateExecutor
和QuerydslBinderCustomizer
在存储库中定义自己的QueryDSL绑定:
public interface FooRepository
extends CrudRepository<Foo, Integer>, QueryDslPredicateExecutor<Foo>, QuerydslBinderCustomizer<QFoo> {
default void customize(final QuerydslBindings bindings, final QFoo foo) {
SingleValueBinding<NumberPath<Integer>, Integer> singleBinding = new SingleValueBinding<NumberPath<Integer>,Integer>(){
@Override
public Predicate bind(NumberPath<Integer> path, Integer ageValue) {
return path.gt(ageValue);
}
};
bindings.bind(foo.age).first(singleBinding);
}
}
I'm no Query DSL expert, but my understanding is the following: 我不是Query DSL专家,但是我的理解是:
a binding defines how a specific field is to be compared to its database column. 绑定定义如何将特定字段与其数据库列进行比较。
The same binding with java 8 lambda: (path, ageValue) -> path.gt(ageValue)
. 与Java 8 lambda相同的绑定: (path, ageValue) -> path.gt(ageValue)
。 You have to read the code in customize method from the url parameter's perspective: 您必须从url参数的角度阅读customize方法中的代码:
fetch the Foos for which the age provided as parameter is greater than the database's value. 获取其参数作为参数提供的年龄大于数据库值的Foos。
Custom Query DSL binding - between comparison 自定义查询DSL绑定-比较之间
Another option is to provide lower and upper bound for your parameter, like this: ?age=10&age=30
. 另一个选择是为您的参数提供上下限,例如: ?age=10&age=30
。 Then, define the following binding: 然后,定义以下绑定:
default void customize(final QuerydslBindings bindings, final QFoo foo) {
bindings.bind(foo.age).all((path, values) -> {
Iterator<? extends Long> it = values.iterator();
return path.between(it.next(), it.next());
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.