【问题标题】:JPA one to many with many childernJPA 一对多与许多孩子
【发布时间】:2021-09-25 05:56:22
【问题描述】:

假设我有一个带有@OneToMany 注释的实体A,它引用了一个具有@ManyToOne 注释的类B,即B 是A 的子级。

当我有很多孩子时,我可以建模吗?说成千上万……例如,我有一个表 B 有 6000 行,表 A 有一个外键。带有@OneToMany 的 JPA 是否适合这份工作?

【问题讨论】:

  • 你是在问使用这样的注解会不会出现性能问题?
  • 是的,如果性能受到影响,还有其他解决方案吗?

标签: jpa one-to-many


【解决方案1】:

简短的回答是:视情况而定 ...

这样的注释只声明你的实体如何连接以及它们如何相互依赖(与表格中的行数无关)......当使用它们时,JPA 提供程序允许您:

  1. 创建通过实体路径导航的 JPA 查询。

  2. 为您将实体加载到内存中,无需自己创建/执行其他查询,只需访问任何实体上的 getter 或 setter ...

可能会出现“性能问题”,具体取决于您的用例、您的数据有多大、您如何访问数据以及其他条件(顺便说一下,我之所以引用,是因为可能再多几秒钟就无法成为你的瓶颈)......让我举几个例子。

假设我们的实体是:DepartmentEmployee...一个Department 可以有多个Employees(因此它会有一个注释为@OneToMany 的员工列表)...一个@ 987654331@ 只能在一个Department 中工作(因此它将有一个注释为@ManyToOne 的部门属性)...

您可能遇到的加载问题:

问题#1:您需要从数据库中加载一个Employee...默认情况下,@ManyToOne 有一个EAGER 获取计划,这意味着一旦您加载了一个@ 987654337@,JPA Provider 也会为您加载他关联的Department(为此,它将执行另一个查询)。这里的问题是您的用例可能不需要Department 信息,并且JPA 提供程序会无缘无故地访问数据库。 解决方案:将@ManyToOne标记为获取LAZY

问题#2:您将@ManyToOne 标记为获取LAZY,但您有一个业务案例,您确实需要Employee 加上他的Department 信息......只想在一次访问数据库(仅一次查询)中完成此操作,并避免 JPA 提供程序在问题 #1 中所做的事情。 解决方案:您可以使用fetch 图表加载您的Employee 实体。

问题#3:您正在加载一组Employees,并且您需要访问他们的Department 信息...您加载这样的组,对于每个员工,您访问他的部门为:employees.stream().map(Employee::getDepartment) ... 你注意到 JPA 提供程序调用数据库 N 次来获取部门信息......这被称为:N+1 problem(你可以搜索它)......解决方案:使用获取图形或配置您的 JPA Provider 以使用 batch strategy 加载实体。

问题#4:您需要加载一个Department 并访问它的所有Employees ...您注意到通过执行:department.getEmployees(),需要一些时间来加载将所有数据放入内存。 解决方案:检查你的数据库模型,可能需要有一些索引。

问题#5:您需要加载一个Department 并访问它的所有Employees ...您有索引等等,但您确定这些表有数百万行...您不需要一次加载所有数据,因为它可能会产生OutOfMemoryProblems解决方案:您通过循环和使用批量策略加载Employees(请参阅MaxResultsFirstResult

如您所见,问题和解决方案与业务案例密切相关。

总结一下,

  1. 使用注释,并使用您计划在生产中遇到的数据样本进行一些测试,运行您的数字。根据经验,建立关系总是一个好主意fetch=LAZY

  2. 如果您认为存在性能问题,请先启用 JPA 提供程序调试模式。它将向您显示正在执行的查询,并帮助您检测您面临的问题...

  3. 确定问题后,开始考虑您的业务案例提出解决方案。请记住,没有灵丹妙药或万能的解决方案,因此正确的解决方案将与您的用例相关联...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 2013-04-13
    • 2018-11-13
    • 2018-02-12
    • 1970-01-01
    相关资源
    最近更新 更多