Optimization 如何高效地查询三个相关表(JPA-QL)
假设我有实体A,B,C,每个A都有许多B和C实体。我想根据一些标准查询a实体的负载a,我知道我将访问每个a返回的所有B和C实体 类似于Optimization 如何高效地查询三个相关表(JPA-QL),optimization,jpa,join,Optimization,Jpa,Join,假设我有实体A,B,C,每个A都有许多B和C实体。我想根据一些标准查询a实体的负载a,我知道我将访问每个a返回的所有B和C实体 类似于从a中选择a作为连接获取a.b连接获取a.c的内容一开始似乎是有意义的,但是如果b和c实体的数量很大,这会产生一个巨大的乘积。将其扩展到另一个关联实体会使查询完全不合理 如果我把JPA留给它自己的设备,那么当它想要访问B和C实体时,我会选择n+1 我想我应该做的是查询一个连接获取B,然后查询一个连接获取C,但这不起作用,因为它给了我两个列表结果,每个结果只有一半的
从a中选择a作为连接获取a.b连接获取a.c
的内容一开始似乎是有意义的,但是如果b和c实体的数量很大,这会产生一个巨大的乘积。将其扩展到另一个关联实体会使查询完全不合理
如果我把JPA留给它自己的设备,那么当它想要访问B和C实体时,我会选择n+1
我想我应该做的是查询一个连接获取B,然后查询一个连接获取C,但这不起作用,因为它给了我两个列表结果,每个结果只有一半的信息
用SQL术语来说,这是一个非常简单的查询,我很失望没有一个明显的方法来处理这个问题。我错过什么了吗
提供者是toplink essentialsJPA至少应该提到对象。你不这样做的事实向我表明,你不会充分利用JPA
如果您有一个遗留模式,而对象模型没有意义,那么您可能不应该使用JPA
JPA无意成为SQL的替代品。它解决了对象关系不匹配的问题。如果没有对象,只需下拉到JDBC和SQL即可
我不知道你的表代表什么,但是如果你在考虑对象,你应该谈论1:m和m:n的关系。一旦有了这些,您就可以使用缓存、延迟和快速抓取来优化对象的填充
更新:编写查询,使每个产品都有其选项和价格列表作为1:m关系,并执行即时抓取。这将避免(n+1)问题
你怎么能说关系和急切的抓取在这里没有帮助
尝试在对象中表达关系,让JPA向您展示它生成的SQL,并将其与您要编写的内容进行比较。如果满意的话,就去做吧。如果没有,请转到JDBC,看看您是否可以做得更好。JPA至少应该提到对象。你不这样做的事实向我表明,你不会充分利用JPA
如果您有一个遗留模式,而对象模型没有意义,那么您可能不应该使用JPA
JPA无意成为SQL的替代品。它解决了对象关系不匹配的问题。如果没有对象,只需下拉到JDBC和SQL即可
我不知道你的表代表什么,但是如果你在考虑对象,你应该谈论1:m和m:n的关系。一旦有了这些,您就可以使用缓存、延迟和快速抓取来优化对象的填充
更新:编写查询,使每个产品都有其选项和价格列表作为1:m关系,并执行即时抓取。这将避免(n+1)问题
你怎么能说关系和急切的抓取在这里没有帮助
尝试在对象中表达关系,让JPA向您展示它生成的SQL,并将其与您要编写的内容进行比较。如果满意的话,就去做吧。如果没有,请转到JDBC,看看您是否可以做得更好。我想知道您为什么说这在SQL术语中非常简单。你不也有笛卡尔积吗
使用JPA的Hibernate提供程序,您提到的一个选项可以工作:
查询连接获取B,然后查询连接获取C
您有两个相同值的列表,您只使用一个,这很好(您只需要左连接)
在Hibernate中,您还可以要求在第二个查询中获取丢失的数据
使用fetch=“subselect”
看
在对原始海报发表评论后更新了:
在java中,您也可以手动执行此操作
在名为entityAs的列表中获取As及其B集合
获取As及其Cs集合(重用部分查询或使用ID)
为第二个查询创建datastructure Map>(为了提高性能,避免内部循环)
循环列表entityAs,使用映射为每个实例A设置集合Cs
这也会有很好的表现
如果您多次遇到这种需要,您可以编写一个参数化方法来完成这项工作,因此只需编写一次代码
正如原始海报所评论的,在修改之前,您需要将所有A实体与entityAs分离,以确保不会向数据库发送更新
我想知道你为什么说这在SQL术语中非常简单。你不也有笛卡尔积吗
使用JPA的Hibernate提供程序,您提到的一个选项可以工作:
查询连接获取B,然后查询连接获取C
您有两个相同值的列表,您只使用一个,这很好(您只需要左连接)
在Hibernate中,您还可以要求在第二个查询中获取丢失的数据
使用fetch=“subselect”
看
在对原始海报发表评论后更新了:
在java中,您也可以手动执行此操作
在名为entityAs的列表中获取As及其B集合
获取As及其Cs集合(重用部分查询或使用ID)
为第二个查询创建datastructure Map>(为了提高性能,避免内部循环)
循环列表entityAs,使用映射为每个实例A设置集合Cs
这也会有很好的表现
如果您多次遇到这种需要,您可以编写一个参数化方法来完成这项工作,因此只需编写一次代码
正如原始海报所评论的,在修改之前,您需要将所有A实体与entityAs分离,以确保不会向数据库发送更新
“我想知道你为什么说这是p