如何使用MongoRepository

时间:2018-02-15 15:49:01

标签: spring-data-mongodb

假设域对象(MyDomain)有很多文件(f1,f2,f3 ... f100),从MongoRepository定义一个MyDomainRepository,我想把字段名和值作为参数而不是硬编码字段名称作为一部分查询方法,如下所示:

List<MyDomain> findByNameAndValue(string name, string value);

如果名称和值是&#34; f1&#34;和&#34; foo&#34;,该方法将找到所有文件的字段&#34; f1&#34;等于&#34; foo&#34;。

我用Google搜索了几个小时,没有运气。

任何人的帮助,谢谢!

2 个答案:

答案 0 :(得分:1)

您需要使用QueryDSL谓词。

首先,将以下依赖项添加到pom.xml中(假设您使用maven构建项目):

<dependencies>
    ...
    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-apt</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-mongodb</artifactId>
    </dependency>
    ...
</dependencies>

还要将其添加到您的构建插件中:

<build>
    <plugins>
    ...
    <plugin>
            <groupId>com.mysema.maven</groupId>
            <artifactId>apt-maven-plugin</artifactId>
            <version>1.1.3</version>
            <executions>
                <execution>
                    <goals>
                        <goal>process</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>target/generated-sources/java</outputDirectory>
                        <processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    ...
    </plugins>

您的存储库必须扩展QueryDslPredicateExecutor:

public interface MyDomainRepository extends MongoRepository<MyDomain, String>,
                                             QueryDslPredicateExecutor<MyDomain> { }

然后您的存储库将继承

public Iterable<MyDomain> findAll(Predicate predicate)

few other methods

构建项目时,QueryDSL将为您生成Q类,您可以使用它来以编程方式构建与谓词匹配的谓词和查询文档:

QMyDomain q = QMyDomain.mydomain;
Predicate p = q.f1.eq(value);

Iterable<MydDomain> 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);
    }
}

最后一段代码是快速而肮脏的,它可能不会按原样运行(至少返回某种List),但你明白了。

答案 1 :(得分:1)

pvpkiran是对的,没有开箱即用的东西。您需要使用注入的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);
}

有趣的是,您可以更进一步,使用Map传递几个名称/值:

List<MyDomain> findByNamesAndValues(Map<String, String> parameters) {

    Document document = new Document(parameters);
    Query query = new BasicQuery(document.toJson());

    return mongoTemplate.find(query, 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);
}

这些方法可以进一步改进以处理分页,以及其他冷却功能,例如字段包含/排除。