如何在mongo spring boot中默认为所有查询添加默认条件
Posted
技术标签:
【中文标题】如何在mongo spring boot中默认为所有查询添加默认条件【英文标题】:How to add default criteria to all the queries by default in mongo spring boot 【发布时间】:2021-08-03 13:41:13 【问题描述】:我需要软删除给定 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 文档。
【问题讨论】:
【参考方案1】:我认为最好的方法是扩展 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 将为您的所有查询添加附加条件。
你也可以用类似的方式覆盖方法findOne
、find
、findAndModify
等等,但是有很多这些方法都使用doFind*
方法。因此覆盖doFind*
将导致使用所有查找查询。并且不要忘记覆盖findById
(它也在内部使用doFindOne
)。
顺便说一句,@Where
注解来自 Hibernate,但 Spring Data Mongo 不使用它们。它需要自己的注释才能与您的实体一起使用。
【讨论】:
感谢您的回答。它可以直接访问 mongo 模板和执行条件。但是当我尝试执行方法查询时,我发现即使方法查询使用 mongo 模板,它也使用内部不同的方法来执行它们。此外,它们在包级别受到保护,因此无法访问。<S, T> List<T> doFind(String collectionName, Document query, Document fields, Class<S> sourceClass, Class<T> targetClass, CursorPreparer preparer)
受包保护。当我们使用方法查询时,我找不到注入的位置。
我针对该问题发布了一个单独的问题***.com/questions/67531458/…
@IrunikaLakmalWeeraratne 感谢您的报告。我为您的问题找到了另一种解决方案,并将在此处进行描述。以上是关于如何在mongo spring boot中默认为所有查询添加默认条件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Spring Boot 在 Mongo 中存储原始 JSON
如何在 Spring Boot 中自动增加 mongo db?
Spring Boot 和 Mongo - 如何通过嵌套属性进行查询