【问题标题】:How to add default query criteria for all the queries when using method queries in spring boot mongodb在spring boot mongodb中使用方法查询时如何为所有查询添加默认查询条件
【发布时间】:2021-08-04 11:00:44
【问题描述】:

我需要对给定的 mongo 数据库执行方法查询并检索数据。但为此,我必须检查字段 delete=false(Soft delete) 是否用于所有查询。

可以通过如下查询来实现

例如:Optional<User> findByIdAndDeletedIsFalse(String id);

但正如您所见,我们必须为所有查询输入DeletedIsFalse。 我尝试了How to add default criteria to all the queries by default in mongo spring boot 中提供的答案,但我发现它只能在我们直接使用 mongo 模板运行查询时使用。

经过一些调试,我发现即使方法查询是通过 Mogno 模板执行的,它们也是使用包保护的类和方法来执行的。所以它们不能被继承的类覆盖。 我找不到让他们执行的入​​口点以及为方法查询注入默认条件的位置。

例如:如果我们检查MongoTemple 的实现,最后执行是通过一个方法发生的

<S, T> List<T> doFind(String collectionName, Document query, Document fields, Class<S> sourceClass, Class<T> targetClass, CursorPreparer preparer)

并且该方法是从名为ExecutableFindOperationSupport 的内部类调用的。所有这些类都是包保护的。

是否有任何理由让它们受到包保护而不给从继承类覆盖它们的机会? 还有没有其他方法可以使用默认条件运行方法查询而不将它们附加到所有查询?

【问题讨论】:

    标签: java spring mongodb spring-boot mongodb-query


    【解决方案1】:

    正如我在上一个问题中所建议的那样,扩展MongoTemplate 的主要问题是需要覆盖很多方法,因为 MongoTemplate 在其内部工作中使用了所有这些方法。这种方式既不灵活也不健壮。

    想向您推荐另一种解决方案。您可以在调用 MongoTemplate 方法之前实现执行某些代码的 Aspect。您只需将附加条件添加到MongoTemplate 收到的每个查询。

    spring-boot-starter-aop 添加到您的依赖项中。在配置类中启用 AOP:

    @Configuration
    @EnableAspectJAutoProxy
    public class AspectConfiguration {
    }
    

    并实现一个可以完成所有工作的小方面:

    @Aspect
    @Component
    public class RepositoryAspect {
        @Before("execution(* org.springframework.data.mongodb.core.MongoTemplate.*(..))()")
        public void before(JoinPoint joinPoint) throws Throwable {
            Object[] args = joinPoint.getArgs();
            for (Object arg : args) {
                if (arg instanceof Query) {
                    Query query = (Query) arg;
                    // add your criteria to the query
                    return;
                }
            }
        }
    }
    

    但请记住,这种方法可能会导致执行查询的性能不佳。如果您构建一个高负载系统,那么设置您的标准是更好的方法 - 这是快速工作的成本。

    【讨论】:

    • 感谢您的回答。我会检查这个。但正如您所提到的,我们正在计划高负载。因此,最好权衡开发人员以维护软删除。但是我们知道为什么这些方法是包私有的吗?我觉得应该可以继承。这是某种设计决策吗?
    • @IrunikaLakmalWeeraratne 这种方法似乎只在ExecutableFindOperationSupport.ExecutableFindSupport 中使用,其他地方没有。这个类和 MongoTemplate 都在包org.springframework.data.mongodb.core 中。因此,使该方法成为私有包确实看起来像是一个设计决策。无论如何,您也可以在您的项目中创建该包并在那里使用覆盖的方法实现 MongoTemplate。这是可能的,因为spring-data-mongo.jar 不是密封的 JAR,并且一个包的类可以位于不同的位置 - 在库和您的应用程序中。
    • 已确认。谢谢!将按照我们的要求坚持使用 mongo 模板。
    猜你喜欢
    • 2021-08-03
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    • 2017-01-06
    • 2019-10-05
    相关资源
    最近更新 更多