gpt4 book ai didi

java - 用于检索复杂实体的高效 JPQL 查询

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:15:26 26 4
gpt4 key购买 nike

我是 JPA/JPQL 的菜鸟,所以如果这个问题不是很清楚,请原谅。

我试图找到一个高效的 JQPL 查询,以便获取复杂对象的所有记录。

(即由多个表表示,具有多个一对多关系 - 请参见下面的简化示例):

class ComplexObject {
private Set< SubOject1> so1 ...
.....
@OneToMany(fetch = FetchType.LAZY)
public Set< SubOject1>...
}

class SubObject1 {
private Set< SubOject2> so2 ...
.....
@OneToMany(fetch = FetchType.LAZY)
public Set< SubOject2>...
}

我正在使用以下 JPQL 查询:

select distinct CO 
from ComplexObject CO
left join fetch CO.so1 SO1
left join fetch SO1.so2

查询在无状态 session 上运行,以获取数据库中当前数据的实际快照,该快照与实体管理器分离(因此使用左连接提取)。

不幸的是,我遇到了两个问题:

  1. 由于复杂对象包含多个 so1 实例,并且每个 so1 实例包含多个 so2 实例,因此对 SQL 查询的底层转换会为所有表连接的产品的每行生成一个特定的选择查询 - 一个非常浪费的解决方案。有没有办法减少内部选择查询的数量? (这似乎是可怕的 N+1 查询问题)。

  2. JPQL 查询针对所有表连接的产品的每个内部 SQL 查询返回一个 ComplexObject 实例 - 这意味着对 ComplexObject 实例的多个引用。为什么在“选择不同”查询时会发生这种情况?

我使用的JPA框架是hibernate,DB是HyperSQL。

结果 (1) 问题与使用 p6spy 日志记录框架有关,该框架打印出大型数据库表中的所有结果。日志记录格式导致错误假设许多查询正在执行。

在尝试微调性能时,使用 native 查询似乎没有比使用 JPQL 查询更好的性能。使用 native 查询还会产生对象类型的结果,这需要进行后处理。

最佳答案

您可以使用 View 对象只接收您想要的列:

StringBuilder sb = new StringBuilder();
sb.append(" SELECT new ").append(ObjectVO.class.getName()).append("(co.someInfo1, co.someInfo2, so1.someInfo )");
sb.append(" FROM ComplexObject co ");
sb.append(" JOIN co.subOject1s so1 ");
sb.append(" LEFT JOIN so1.so2 so2 ");
sb.append(" WHERE so1.id = :idSo1 AND so2 = :someThing");

Query q = em.createQuery(sb.toString());
q.setParameter("idSo1", idSo1);
q.setParameter("someThing", someThing);

List<ObjectVO> listResult = q.getResultList();

ObjectVO 类:

public class ObjectVO {

private String info1;
private Long info2;
private String info3;

public PedidoModel(String info1, Long info2, String info3){
this.info1 = info1;
this.info2 = info2;
this.info3 = info3;
}

}

关于java - 用于检索复杂实体的高效 JPQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36451190/

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