如何加速 JPA 中的列表访问

Posted

技术标签:

【中文标题】如何加速 JPA 中的列表访问【英文标题】:How to speed up List access in JPA 【发布时间】:2014-07-28 01:16:50 【问题描述】:

在我的映射器类中,我总是需要从我的公司实体中检索部门列表:

  @OneToMany(mappedBy = "company", orphanRemoval = true, cascade = CascadeType.ALL)
  public List<CompanyDepartments> getDepartments()
  
    return departments; //java.util.List variable. 
  

有几千个部门(大约 2000 多个)。我正在尝试减少获取公司数据所需的时间,并希望从本质上相当静态的部门开始。

选项 1: 我总是可以在映射器中有一个私有方法,该方法在第一次加载时填充缓存并始终从缓存中返回。 但是还有什么更简单的吗?我可能不是第一个面对这个问题的人,我想知道我该如何解决这个问题。是否有可以使用的已知注释。就像实体中变量上的 @Singleton 注释一样? (显然没有这样的注释)。使此列表成为单例的最简单方法是什么。

只是一个典型的 spring mvc 3 应用程序,使用 spring data jpa 进行 db 交互。

【问题讨论】:

【参考方案1】:

我建议这个链接可以解决 n+1 查询问题... How can i resolve the N+1 Selects problem?

此外,您可以在搜索服务上放置一个缓存(2 级), 如果数据在应用程序的生命周期内没有变化。 http://docs.spring.io/spring/docs/3.1.0.M1/spring-framework-reference/html/cache.html

另一种方法是添加到数据库上的索引。

我希望我已经为您提供了有关您问题的所有答案。

【讨论】:

【参考方案2】:

您遇到的是“对象关系阻抗不匹配”的一部分。一种解决方案是扩展您的对象模型,以便您可以使用 left join fetch 仅使用一条 SQL 语句来加载多个公司,包括他们的部门。

使用这种技术的问题是您一次只能填充一个列表。尽管在对象的世界中定义许多子列表很好也很容易,但很难从关系数据库中同时(因此有效地)加载所有这些列表。然而,可以在 Oracle 上使用对象或 XMLType 查询来完成。

从 RDBMS 中获取此类数据的直接方法是编写与手头任务完全匹配的自定义查询,并仅提供实际需要的数据。 因此,您不仅需要一个公司类,还需要多个 - 每个任务一个。 - 实际上,您需要进行继承而不是归属

顺便说一句,这就是为什么 ORM 仍然被认为是 Vietnam of Computer science - 容易上手,但很难成功。

【讨论】:

以上是关于如何加速 JPA 中的列表访问的主要内容,如果未能解决你的问题,请参考以下文章

如何访问实体列表中的另一列?

如何使用 Hibernate 和 JPA 处理填充下拉列表?

JPA 中的传递列表命名本机查询

JPA将列表传递给命名本机查询中的IN子句

如何在本机查询中使用 NVL 或 COALESCE 获取 Spring Data JPA 中的值列表

如何添加到列表的链接以使用 spring-jpa 进行排序?