Spring data mongodb 如何使用MongoRepository查询任何字段
假设域对象(MyDomain)有许多文件(f1、f2、f3…f100),从MongoRepository中定义MyDomainRepository,我想将字段名和值作为参数,而不是将字段名硬编码作为查询方法的一部分,如下所示:Spring data mongodb 如何使用MongoRepository查询任何字段,spring-data-mongodb,Spring Data Mongodb,假设域对象(MyDomain)有许多文件(f1、f2、f3…f100),从MongoRepository中定义MyDomainRepository,我想将字段名和值作为参数,而不是将字段名硬编码作为查询方法的一部分,如下所示: List<MyDomain> findByNameAndValue(string name, string value); 列出findByNameAndValue(字符串名称、字符串值); 如果名称和值为“f1”和“foo”,则该方法将查找字段“f1”等
List<MyDomain> findByNameAndValue(string name, string value);
列出findByNameAndValue(字符串名称、字符串值);
如果名称和值为“f1”和“foo”,则该方法将查找字段“f1”等于“foo”的所有文档
我在谷歌上搜索了好几个小时,但运气不好
任何人的帮助,谢谢 您需要使用谓词
首先,将以下依赖项添加到pom.xml(假设您使用maven构建项目):
...
com.querydsl
构建项目时,QueryDSL将为您生成Q类,您可以使用该类以编程方式构建谓词并查询与谓词匹配的文档:
QMyDomain q = QMyDomain.mydomain;
Predicate p = q.f1.eq(value);
Iterable<MydDomain> i = repository.findAll(p);
QMyDomain q=QMyDomain.mydomain;
谓词p=q.f1.eq(值);
Iterable i=repository.findAll(p);
要使用REST控制器查询资源,您需要类似以下内容:
@RestController
@RequestMapping(/"mydomain")
public class MyDomainController {
@Autowired private MyDomainRepository repository;
@GetMapping("/search/query")
public List<MyDomain> query(@QuerydslPredicate(root = MyDomain.class) Predicate predicate) {
return repository.findAll(predicate);
}
}
@RestController
@请求映射(/“mydomain”)
公共类MyDomainController{
@自动连线私有MyDomainRepository存储库;
@GetMapping(“/search/query”)
公共列表查询(@QuerydslPredicate(root=MyDomain.class)谓词){
返回repository.findAll(谓词);
}
}
最后一段代码是快速而肮脏的,它可能不会按原样工作(至少返回某种类型的列表),但你明白了。你需要使用谓词
首先,将以下依赖项添加到pom.xml(假设您使用maven构建项目):
...
com.querydsl
构建项目时,QueryDSL将为您生成Q类,您可以使用该类以编程方式构建谓词并查询与谓词匹配的文档:
QMyDomain q = QMyDomain.mydomain;
Predicate p = q.f1.eq(value);
Iterable<MydDomain> i = repository.findAll(p);
QMyDomain q=QMyDomain.mydomain;
谓词p=q.f1.eq(值);
Iterable i=repository.findAll(p);
要使用REST控制器查询资源,您需要类似以下内容:
@RestController
@RequestMapping(/"mydomain")
public class MyDomainController {
@Autowired private MyDomainRepository repository;
@GetMapping("/search/query")
public List<MyDomain> query(@QuerydslPredicate(root = MyDomain.class) Predicate predicate) {
return repository.findAll(predicate);
}
}
@RestController
@请求映射(/“mydomain”)
公共类MyDomainController{
@自动连线私有MyDomainRepository存储库;
@GetMapping(“/search/query”)
公共列表查询(@QuerydslPredicate(root=MyDomain.class)谓词){
返回repository.findAll(谓词);
}
}
这最后一段代码是快速而肮脏的,它可能不会按原样工作(至少返回某种列表),但你明白了。pvpkiran是对的,没有现成的东西。您需要使用注入式MongoTemplate构建自己的MongoTemplate,例如:
List<MyDomain> findByNameAndValue(string name, string value) {
Document document = new Document(name, value);
Query query = new BasicQuery(document.toJson());
return mongoTemplate.find(query, MyDomain.class);
}
列出findByNameAndValue(字符串名称、字符串值){
文件=新文件(名称、值);
Query Query=newbasicquery(document.toJson());
返回mongoTemplate.find(查询,MyDomain.class);
}
有趣的是,您可以进一步使用映射传递多个名称/值:
List<MyDomain> findByNamesAndValues(Map<String, String> parameters) {
Document document = new Document(parameters);
Query query = new BasicQuery(document.toJson());
return mongoTemplate.find(query, MyDomain.class);
}
列出findByNamesAndValues(映射参数){
文件=新文件(参数);
Query Query=newbasicquery(document.toJson());
返回mongoTemplate.find(查询,MyDomain.class);
}
以防万一,这也适用于QueryDSL谓词:
List<MyDomain> findByNamesAndValues(Predicate predicate) {
AbstractMongodbQuery mongoQuery = new SpringDataMongodbQuery(mongoTemplate, MyDomain.class)
.where(predicate)
Query query = new BasicQuery(mongoQuery.toString());
return mongoTemplate.find(query, MyDomain.class);
}
列出findByNamesAndValues(谓词){
AbstractMongoDB查询mongoQuery=新的SpringDataMongoDB查询(mongoTemplate,MyDomain.class)
.where(谓词)
Query Query=newbasicquery(mongoQuery.toString());
返回mongoTemplate.find(查询,MyDomain.class);
}
这些方法可以进一步改进以处理分页和其他cools功能,如字段包含/排除。pvpkiran是正确的,没有现成的东西。您需要使用注入式MongoTemplate构建自己的MongoTemplate,例如:
List<MyDomain> findByNameAndValue(string name, string value) {
Document document = new Document(name, value);
Query query = new BasicQuery(document.toJson());
return mongoTemplate.find(query, MyDomain.class);
}
列出findByNameAndValue(字符串名称、字符串值){
文件=新文件(名称、值);
Query Query=newbasicquery(document.toJson());
返回mongoTemplate.find(查询,MyDomain.class);
}
有趣的是,您可以进一步使用映射传递多个名称/值:
List<MyDomain> findByNamesAndValues(Map<String, String> parameters) {
Document document = new Document(parameters);
Query query = new BasicQuery(document.toJson());
return mongoTemplate.find(query, MyDomain.class);
}
列出findByNamesAndValues(映射参数){
文件=新文件(参数);
Query Query=newbasicquery(document.toJson());
返回mongoTemplate.find(查询,MyDomain.class);
}
以防万一,这也适用于QueryDSL谓词:
List<MyDomain> findByNamesAndValues(Predicate predicate) {
AbstractMongodbQuery mongoQuery = new SpringDataMongodbQuery(mongoTemplate, MyDomain.class)
.where(predicate)
Query query = new BasicQuery(mongoQuery.toString());
return mongoTemplate.find(query, MyDomain.class);
}
列出findByNamesAndValues(谓词){
AbstractMongoDB查询mongoQuery=新的SpringDataMongoDB查询(mongoTemplate,MyDomain.class)
.where(谓词)
Query Query=newbasicquery(mongoQuery.toString());
返回mongoTemplate.find(查询,MyDomain.class);
}
这些方法可以进一步改进,以处理分页和其他cools功能,如字段包含/排除。使用存储库方法是不可能的。为此,您必须使用MongoTemplate。使用存储库方法是不可能的。你必须使用MongoTemplate来解决这个问题我意识到这个答案实际上更像是“初学者的QueryDSL”,而不是你问题的准确答案。我意识到这个答案实际上更像是“初学者的QueryDSL”,而不是你问题的准确答案。谢谢,很好的一点,我正在研究MongoTemplate和QueryDSL,因为当前项目使用MongoRepository,如果可能的话,考虑将MongoTemplate/QueryDSL和MongoRepository结合起来(目前我还不确定)。我有一个项目,在这个项目中,我使用了这两个世界中最好的一个:扩展MongoRepository和QueryDSL PredicateExecutor的存储库(参见我的另一个答案)以及使用mongoTemplate和QueryDsl的自定义服务类。这将为您提供查询数据所需的一切。实际上,不,代码属于向我付款的客户:)它基本上使用了我在两个answe中显示的内容