【发布时间】:2016-05-04 02:54:19
【问题描述】:
首先我将解释我是如何理解和使用 @BatchSize 的:
@BatchSize是为了批量加载对象的关系,减少对数据库的SQL请求。这对 LAZY @OneToMany 关系特别有用。
然而,它甚至对 LAZY @OneToOne 关系和 @ManyToOne 有用:如果您从数据库加载实体列表并要求加载延迟的 @*ToOne 实体,它将加载即使我只是使用加载列表第一个实体的关系的测试,也可以批量处理实体。
如果有人想测试,请注意:这仅显示实体是否尚未加载:例如,如果您有一个带有经理的用户列表并列出所有用户,当您访问经理时,不会触发任何请求因为它已经加载了。
我在该方法中看到的唯一缺点是,如果您从数据库加载项目列表但只使用其中的一部分。这是一个后过滤操作。
让我们进入重点。
让我们假设我做的一切都很好,永远不要做类似后过滤的操作,即使它让我做原生 SQL 查询或使用 DTO 对象进行多选条件查询等等。
- 在仔细考虑使用急切加载/加入并最终选择一个惰性关系之后,我是否可以考虑
@BatchSize每个惰性关系? - 我是否有兴趣为
@BatchSize寻找足够的价值,或者我可以认为“越大越好”?这将意味着““IN”SQL 运算符中是否有任何数量限制可以使我的请求足够慢以至于不再值得?我使用 Postgres 但如果你有其他 SGBD 的答案,我也很感兴趣。 - 可选问题:似乎在课堂上使用
@BatchSize并没有产生很多结果。我仍然需要注释每一个懒惰的关系,是我错过了什么还是没用?
编辑:我的 3 点是我得到了不同的行为。
假设我正在加载与 B 具有 LAZY OneToMany 关系的“A”类实体列表。现在我想打印 B 的所有 creationDate。所以我正在做一个经典的 2 for 循环。
我现在用 BatchSize 注释 B:
- @OneToMany 未使用 BatchSize 注释:每组 B 在每次迭代中独立加载,无需批处理。所以我对 B 类的注释似乎完全被忽略了。即使我将一个值设置为“两个”并且我在一组中有 6 个条目,我也对该组有一个查询。
- @OneToMany 已注释:我有已加载批次的特定查询。如果我将批量大小固定为 2,并且我总共有 10 个 B accro,我只会收到 5 个请求:无论我有多少 A。如果我将其设置为 100:我有 1 个查询 B 对象。
PS:我没有考虑任何与 B 相关的查询,这些查询可能会触发以使用 fetch select/subselect 加载 B 字段。
编辑 2:我刚刚发现这篇文章 Why would I not use @BatchSize on every lazy loaded relationship? 虽然我在发布我的问题之前用谷歌搜索并搜索了 SO,但我猜我没有使用正确的词...
但是我添加了一些不同的东西,这可能会导致不同的答案:当我想知道在每个关系上使用 BatchSize 时,它是在选择我是否想要急切加载、加入/选择获取或我想要懒惰之后正在加载。
【问题讨论】:
标签: java hibernate postgresql jpa