java - 自定义 Spring MongoRepository - 按类过滤

标签 java spring mongodb spring-data

我有几个 Java 文档存储在 mongodb 的同一个集合“app”中。我的意图是将它用于常见的持久性操作(插入、查找、删除...)。当我尝试只为其中一个类定义存储库时,问题就来了,因为我定义的存储库将搜索所有实体,而我需要的是一个存储库,我可以在其中调用所有 mongorepository 标准函数(find、findAll ,查找...)。我的解释可能很难理解,这就是我现在的:

基础文档:

@Document(collection = "app")
@NoRepositoryBean
public abstract class AbstractApplicationDocument {    
    @Id
    public String mongoId;
    // more variables, getters, setters...
}

其中一个子文档(会有很多)。

@EqualsAndHashCode(callSuper=true)
public class ClientApplicationDocument extends AbstractApplicationDocument
{
    @Id
    public String mongoId;    
}

基础仓库

@NoRepositoryBean
public interface ApplicationRepository<T, ID extends Serializable>  extends MongoRepository<T, ID>  {

}

扩展存储库(我想按类过滤的地方)

public interface HttpClientRepository extends ApplicationRepository<HttpClientDocument, String> {
}

如果我可以重用 MongoDb 实用程序,我想避免的临时解决方案示例

@Component
public class HttpClientRepositoryImpl {

    @Autowired
    private HttpClientRepository clientRepo;

    @Autowired
    private MongoTemplate mongo;

    public List<HttpClientDocument> findAll() {    
        Query query = new Query();
        query.addCriteria(Criteria.where("_class").is(HttpClientDocument.class.getName()));
        mongo.getConverter();
        return mongo.find(query, HttpClientDocument.class,"app");
    }
}

gradle中的相关信息。我添加这个是因为我看到了一些对我无效的解决方案。可能是因为他们使用不同的库:

compile("org.springframework.boot:spring-boot-starter-data-mongodb:${springBootVersion}")
compile ("org.springframework:spring-context-support:4.1.8.RELEASE");

有什么简单的解决方法吗?

最佳答案

您可以通过多种方式自定义 Spring Data 存储库。您可以提供自定义存储库基类或提供 custom implementation classes .

特别针对您的问题, SimpleMongoRepository 不限制对 _class 的查询 field 。您可以在下面看到一个限制 findAll 的自定义存储库基类的示例。查询方法只使用声明的实体类型。

对于在 MongoRepository 上声明的其他方法,您也需要应用该模式。您想要限制到特定类类型的级别。

@EnableMongoRepositories(repositoryBaseClass = MyMongoRepository.class)
static class Config {
}

static class MyMongoRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> {

    private final MongoEntityInformation<T, ID> metadata;
    private final MongoOperations mongoOperations;

    public MyMongoRepository(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) {
        super(metadata, mongoOperations);
        this.metadata = metadata;
        this.mongoOperations = mongoOperations;
    }

    @Override
    public List<T> findAll() {

        Query query = new Query();
        query.restrict(this.metadata.getJavaType());

        return this.mongoOperations.find(query, this.metadata.getJavaType(), this.metadata.getCollectionName());
    }
}

findAll查询现在限制类类型和查询,例如ModelRepository extends MongoRepository<Model, String>看起来像:

{ "_class" : { "$in" : [ "com.example.Model"]}}

使用 @Query 查询方法可用于传入类类型 ( @Query("{'_class': ?0}") ),但无法限制派生查询方法 ( List<Model> findByFirstnameAndLastname(…) ) 的类类型。

有一个 open ticket在我们的 Jira 中与限制存储库的类型有关。该特定票证与多态查询有关,但从本质上讲,它与查询方法的类型限制有关。

关于java - 自定义 Spring MongoRepository - 按类过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38302410/

相关文章:

java - 在java中切换值

java - 如何从 Controller 重定向到另一个 Controller 到 POST 方法?

java - 在 IntelliJ IDEA 中使用 Spring-test-mvc 进行测试更简单的方法?备择方案?

javascript - 如何将数据从 mongodb(使用 Mongoose 模块)传递到 Node js View (使用临时引擎 jade)?

c# - 使用 C# 检查数据库中是否存在当前日期

java - IntentService 中的 RemoteException

java - 商店的简单数据库方案

java - 确保 Spring Quartz 作业执行不重叠

node.js - Mongoose 拒绝将有效字符串转换为 ObjectId

java - Spring 3 的异常处理