首页 > 解决方案 > 如何在mongo spring boot中默认为所有查询添加默认条件

问题描述

我需要软删除给定 MongoDB 集合中的文档。为此,我使用了一个名为已删除的布尔值。所以现在当我从数据库中检索数据时,我必须总是提到将数据放在deleted=false.

例如:

public Organization findOrgById(String id) {
    Query query = new Query();
    Criteria criteria = Criteria.where(Constants.ENTITY_ID).is(id)
            .and(Constants.DELETED).is(false);
    query.addCriteria(criteria);
    Organization res = mongoTemplate.findOne(query, Organization.class);
    return res;
}

有没有办法指定deleted=false默认添加的所有条件而不在代码本身中提及它?在 Hibernate 核心中有一个注释@Where,但它不适用于 mongo 文档。

标签: mongodbspring-bootspring-data-jpamongodb-query

解决方案


我认为最好的方法是扩展MongoTemplate将您的deleted=false条件添加到所有 Find 查询的类。

以下是如何使用一种用于执行findOne查询的方法的示例:

public class ExtendedMongoTemplate extends MongoTemplate {

    private static final Document DELETED_CRITERIA_DOC = Criteria.where(Constants.DELETED).is(false)
        .getCriteriaObject();

    @Override
    protected <T> T doFindOne(
            String collectionName,
            Document query,
            Document fields,
            CursorPreparer preparer,
            Class<T> entityClass) {
        query.putAll(DELETED_CRITERIA_DOC);
        return super.doFindOne(collectionName, query, fields, preparer, entityClass);
    }
    ...
}

该方法在方法中被调用doFindOne(Query query, Class<?> entityClass)(最后一个委托执行

其他覆盖的方法是:

protected <S, T> List<T> doFind(String collectionName, Document query, Document fields,
    Class<S> entityClass, CursorPreparer preparer);

protected <T> T doFindAndRemove(String collectionName, Document query, Document fields,
    Document sort, @Nullable Collation collation, Class<T> entityClass);

protected <T> T doFindAndModify(String collectionName, Document query, Document fields, Document sort,
    Class<T> entityClass, UpdateDefinition update, @Nullable FindAndModifyOptions options);

protected <T> T doFindAndReplace(String collectionName, Document mappedQuery, Document mappedFields,
    Document mappedSort, com.mongodb.client.model.Collation collation, Class<?> entityType,
    Document replacement, FindAndReplaceOptions options, Class<T> resultType);

这些方法在低级别执行查询,因此它们接受具有查询条件的 BSON 文档,而不是 Spring 的条件。如果您这样做,Find-methods 将为您的所有查询添加附加条件。

您也可以以类似的方式覆盖 methods findOnefindfindAndModify,但是这些方法中有很多都使用doFind*方法。因此,覆盖doFind*将导致使用所有查找查询。并且不要忘记覆盖findById(它也在doFindOne内部使用)。

顺便说一句,@Where注解来自 Hibernate,但 Spring Data Mongo 不使用它们。它需要自己的注释才能与您的实体一起使用。


推荐阅读