我们有一个用例,用户可以传递集合的任意搜索条件,并希望输出分页。使用Spring Data存储库,如果我们提前知道他们可以通过简单扩展的MongoRepository搜索哪些属性,并声明:
,这非常简单。 Page<Thing> findByFooAndBarAndBaz(Type foo, Type bar, Type baz, Pageable page)
但是,如果我们自己使用fluent接口生成查询或构造mongo字符串并将其包装在BasicQuery
类中,我找不到将其转换为存储库实例的方法。没有:
Page<Thing> findByQuery(Query q, Pageable page)
我能够看到的功能。
我也无法看到如何使用Page抽象来挂钩MongoTemplate
查询功能。
我希望我不必滚动自己的分页(计算跳过和限制参数,我猜这并不难)并直接调用模板,但我想我可以,如果那&# 39;是最好的选择。
答案 0 :(得分:4)
我不认为这可以按照我希望的方式完成,但我想出了一个解决方法。作为背景,我们将所有方法都放在DAO中进行数据访问,一些方法委托给存储库,一些委托给模板。
MongoTemplate#count(Query, Class)
Query#with(Pageable)
MongoTemplate#find(Query, Pageable)
List<T>
结果,用于查询的Pageable
和从countQuery运行返回的count
,并构造一个新的PageImp
以返回致来电者。基本上,这个(DocDbDomain
是用于测试文档db内容的测试域类):
Query countQuery = new BasicQuery(toMongoQueryString(filterString));
Query pageQuery = countQuery.with(pageRequest);
long total = template.count(countQuery, DocDbDomain.class);
List<DocDbDomain> content = template.find(pageQuery, DocDbDomain.class);
return new PageImpl<DocDbDomain>(content, pageRequest, total);
答案 1 :(得分:2)
您可以使用@Query
注释通过存储库方法执行任意查询:
interface PersonRepository extends Repository<Person, Long> {
@Query("{ 'firstname' : ?0 }")
Page<Person> findByCustomQuery(String firstname, Pageable pageable);
}
一般来说,@Query
可以包含您可以通过shell执行的任何JSON查询,但使用?0
种语法来替换参数值。您可以在reference documentation中找到有关基本机制的更多信息。
答案 2 :(得分:0)
如果您无法在@Query
- 注释中表达您的查询,则可以使用Spring存储库PageableExecutionUtils
进行自定义查询。
例如:
@Override
public Page<XXX> findSophisticatedXXX(/* params, ... */ @NotNull Pageable pageable) {
Query query = query(
where("...")
// ... sophisticated query ...
).with(pageable);
List<XXX> list = mongoOperations.find(query, XXX.class);
return PageableExecutionUtils.getPage(list, pageable,
() -> mongoOperations.count(query, XXX.class));
}
与最初的Spring Data Repository一样,PageableExecutionUtils
将执行一个单独的count
请求,并将其包装成一个不错的Page
。
Here你可以看到春天也在做同样的事情。