Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Optimization 如何高效地查询三个相关表(JPA-QL)_Optimization_Jpa_Join - Fatal编程技术网

Optimization 如何高效地查询三个相关表(JPA-QL)

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,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,但这不起作用,因为它给了我两个
列表
结果,每个结果只有一半的信息

用SQL术语来说,这是一个非常简单的查询,我很失望没有一个明显的方法来处理这个问题。我错过什么了吗


提供者是toplink essentials

JPA至少应该提到对象。你不这样做的事实向我表明,你不会充分利用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