gpt4 book ai didi

java - JPA/Hibernate 查询 : load eagerly with subselect

转载 作者:行者123 更新时间:2023-12-05 07:55:44 25 4
gpt4 key购买 nike

情况:“父”实体有多个“子”实体(@OneToMany、@Lazy)- 双向关系。实体上没有外键(“Child#parentId”)字段。

目标:通过使用子选择检索完全加载的父集合来避免 N+1 问题。如果我理解 Subselect 的理论,这就是我的目标(2 个生成的 SQL 查询):

select * from Parent ...;
select * from Child where parent_id in ...;


问题 1:实现此目标的最佳做法是什么?您能否提供 JPQL/HSQL 和 Criteria 中的示例?

问题 2(奖励):API 能否管理“批处理”中的第二次查询划分 - 例如将批处理限制为 500:如果第一个查询加载 1000 个父项,则 2a。为 500 个 parent 加载 child ,2b。加载接下来的 500 个。


我试过:两者都会导致 SQL JOIN,看来我不能在没有 JOIN 的情况下使用 Child 的外键。

// 2nd query:
criteria
.createAlias("parent", "p")
.add(Property.forName("p.id")
.in(parentCriteria.setProjection(Projections.property("id"))))
.list();

// 2nd query (manual):
criteria
.createAlias("parent", "p")
.add(Property.forName("p.id").in(parentIdList))
.list();

更新 (2015-04-05)

我通过提示检查了它在 EclipseLink 中的作用:

query.setHint("eclipselink.batch.type", "EXISTS");

此链接http://blog.ringerc.id.au/2012/06/jpa2-is-very-inflexible-with-eagerlazy.html建议这不可能通过 Hibernate 进行,并建议手动获取。但是我不明白如何通过 HQL 或 Criteria 来实现它,特别是如何获取不在实体上但仅存在于数据库上的 child.parent_id 列。也就是说,避免由 child.parent.id 产生的 JOIN。

最佳答案

为避免 N+1 查询,您可以注释关系

@BatchFetch(BatchFetchType.JOIN)  //in eclipselink or
@BatchSize //in hibernate.

在查询中,您可以添加 fetch to join 子句:

select p from Parent p join fetch p.children c where ...

您还可以添加查询提示

query.setHint("eclipselink.batch", "p.children");

或者使用 EntityGraphs。

关于java - JPA/Hibernate 查询 : load eagerly with subselect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29355112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com