【问题标题】:optimizing findAll in spring Data JPA在 Spring Data JPA 中优化 findAll
【发布时间】:2022-02-02 15:34:01
【问题描述】:

我有一个表,其中包含最多 50 行的查找值列表。 目前,我每次都在查询该表以查找效率不高的特定值。 因此,我计划通过使用 findAll 从存储库中一次加载所有值作为列表来优化这一点。

List<CardedList> findAll();

我的问题是 A 类 -> B 类 - 保存此存储库的 B 类。每次A类调用B类都会查询findAll吗?

 Class A  {
       //foreach items in the list call Class B
        b.someMethod();
    }
    
    
    Class B {
      @Autowired
      CardedListRepository cardRepo;
    
     someMethod() {
             cardRepo.findAll(); 
     }
       
  }

实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: spring-boot java-8 spring-data-jpa


    【解决方案1】:

    如果只有 50 行,您可以将它们缓存在服务的实例变量中并像这样检查:

    Class B {
      @Autowired
      CardedListRepository cardRepo;
      List<CardedList> cardedList = new ArrayList<>();
    
      someMethod() {
         if(cardedList.isEmpty())
         {
             cardedList = cardRepo.findAll();
         }
         // do others in someMethod 
     }
    

    【讨论】:

      【解决方案2】:

      proposed "solution" by @Juliyanage Silva(将findAll 查询结果“缓存”为服务B 的简单实例变量)可能非常危险,在仔细检查之前不应实施它适用于所有情况。

      想象一下从后续事务中调用同一个服务实例 - 您最终会得到一个(可能已过时的)分离实体列表。
      (例如访问未初始化的属性时导致 LazyInitializationExceptions 等)


      Hibernate 已经提供了几种缓存机制,例如标准的一级缓存,可避免在同一事务中按 ID 查找已加载实体时不必要的数据库往返。

      但是,查询结果(来自findAll)默认不缓存,如the documentation 中所述:

      查询结果的缓存会在您的应用程序正常事务处理方面引入一些开销。例如,如果您缓存对 Person 的查询结果,Hibernate 将需要跟踪这些结果何时应该失效,因为已针对任何 Person 实体提交了更改。
      再加上大多数应用程序根本无法从缓存查询结果中获益这一事实,导致 Hibernate 默认禁用查询结果缓存。

      enable the Hibernate query cache,需要配置二级缓存。为了防止在有多个应用程序实例时出现陈旧的条目,这个calls for a distributed cache(如Hazelcast 或EhCache)。


      也有各种关于为此目的使用弹簧缓存机制的讨论。但是,在缓存集合方面也存在各种缺陷。当运行多个应用程序实例时,您可能还需要分布式缓存或其他全局失效机制。

      How to add cache feature in Spring Data JPA CRUDRepository

      Spring Cache with collection of items/entities

      Spring Caching not working for findAll method


      因此,根据您的用例,通过将结果存储在服务A 的调用方法内的局部变量中,避免不必要的服务B 调用可能是最简单的。

      【讨论】:

        猜你喜欢
        • 2018-09-23
        • 1970-01-01
        • 2014-03-29
        • 2018-06-15
        • 2018-01-02
        • 2020-08-18
        • 2023-03-12
        • 1970-01-01
        • 2022-07-21
        相关资源
        最近更新 更多