Spring Data Mongodb:QueryDsl Predicate 和 Criteria API 互操作性 [英] Spring data Mongodb: QueryDsl Predicate and Criteria API interoperability
问题描述
我在 Spring Data Mongodb 中使用 QueryDSL 谓词.但是,我面临着必须将 Query API 与 MongoTemplate 一起使用的情况(例如,过滤要从 Mongo 获取的字段).这是一个简单的例子:
I'm using QueryDSL predicates with Spring Data Mongodb. However, I'm facing situations where I have to use the Query API with MongoTemplate (for instance to filter fields to fetch from Mongo). Here is a simple example:
public Stream<MyModel> findSummary(Predicate predicate){
Query query = new Query();
query.fields.include("field1").include("field2");
return mongoTemplate.stream(query, MyModel.class);
}
我想将谓词转换为标准,以便我可以执行以下操作:
I would like to transform my Predicate into a Criteria so that I could do something like:
Query query = new Query();
query.addCriteria(XXXXX.toCriteria(predicate));
但是我找不到这样的实用程序类.
However I cannot find such utility class.
我发现可以访问 QueryDSL 谓词,因此我开始实现自定义访问者 (com.mysema.query.types.Visitor),但 Criteria API 并非为此目的而设计:例如实现简单的"and" QueryDSL (com.mysema.query.types.Ops#AND) 的操作符必须变成类似
I've found that a QueryDSL Predicate can be visited and so I started implementing a custom Visitor (com.mysema.query.types.Visitor) but the Criteria API was not designed for this purpose: for example implementing the simple "and" operator of QueryDSL (com.mysema.query.types.Ops#AND) has to be turned into something like
<result of left argument visit assumed to be a Criteria>.and("<path of right argument>").<operator of right argument>(<result of right argument visit>);
有人可以建议一种使 QueryDSL Predicates 和 Spring Data Mongodb Query 互操作的方法吗?
Can someone suggest an approach to make QueryDSL Predicates and Spring Data Mongodb Query interoperate ?
谢谢
贝努瓦
推荐答案
我遇到了同样的问题,但在 Internet 上没有找到针对此问题的任何解决方案.经过多次试验&错误,我已经实施了一个在我的项目中运行良好的自定义解决方案,它可能会帮助其他人.
I ran into same problem and did not find any solution on internet for this problem. After many trial & errors, I have implemented a custom solution that works well in my project and it may help others.
注意
使用的版本:
- spring-data-mongodb - 3.0.2.RELEASE
- querydsl - 4.3.1
实现
首先创建一个扩展的类 org.springframework.data.mongodb.repository.support.SpringDataMongodbQuery
&使用 public
修饰符覆盖 createQuery(Predicate predicate)
方法.
first create a class that extends org.springframework.data.mongodb.repository.support.SpringDataMongodbQuery
& override createQuery(Predicate predicate)
method with public
modifier.
public class CustomSpringDataMongodbQuery<T> extends SpringDataMongodbQuery<T> {
public CustomSpringDataMongodbQuery(MongoOperations operations, Class<? extends T> type) {
super(operations, type);
}
@Override
public Document createQuery(Predicate predicate) {
return super.createQuery(predicate);
}
}
现在创建一个实现org.springframework.data.mongodb.core.query.CriteriaDefinition
的类.
public class DocumentCriteria implements CriteriaDefinition {
private final Document criteriaObject;
public DocumentCriteria(Document criteriaObject) {
this.criteriaObject = criteriaObject;
}
@Override
public Document getCriteriaObject() {
return criteriaObject;
}
@Override
public String getKey() {
return null;
}
}
现在您可以使用这两个类从谓词中获取查询.
now you can obtain query from predicate using these two classes.
Document document = new CustomSpringDataMongodbQuery<>(mongoTemplate, MyModel.class).createQuery(predicate);
Query query = Query.query(new DocumentCriteria(document));
投影查询
如果你想使用QClass字段进行投影,那也是可以的.
If you want to use QClass fields for projection, then it's also possible.
在 CustomSpringDataMongodbQuery 类中,添加方法
In CustomSpringDataMongodbQuery class, add method
public Query createQuery(Predicate filter, List<Path<?>> fields) {
QTuple qTuple = Projections.tuple(fields.toArray(new Path[0]));
return createQuery(filter, qTuple, QueryModifiers.EMPTY, Collections.emptyList());
}
并传递路径列表(QClass 字段)以及谓词
and pass list of Path(QClass fields) along with predicate
使用投影和查询进行查询分页
您可以使用
public Query createQuery(Predicate filter, List<Path<?>> fields, int page, int size, List<OrderSpecifier<?>> orderSpecifiers) {
QTuple qTuple = Projections.tuple(fields.toArray(new Path[0]));
QueryModifiers queryModifiers = new QueryModifiers((long) size, (long) (page - 1) * size);
return createQuery(filter, qTuple, queryModifiers, orderSpecifiers);
}
希望这对所有想要使 QueryDSL Predicates 和 Spring Data Mongodb Query 互操作的人有所帮助.
Hope this helps everyone who wants to make QueryDSL Predicates and Spring Data Mongodb Query interoperate.
欢迎提出任何建议!!
这篇关于Spring Data Mongodb:QueryDsl Predicate 和 Criteria API 互操作性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!