【问题标题】:Hibernate - understanding join queries generated using hqlHibernate - 了解使用 hql 生成的连接查询
【发布时间】:2012-06-16 23:28:06
【问题描述】:

使用的休眠版本:

  <artifactId>hibernate-annotations</artifactId>
  <version>3.5.5-Final</version>

  <artifactId>hibernate-core</artifactId>
  <version>3.5.5-Final</version>

  <artifactId>hibernate-commons-annotations</artifactId>
  <version>3.2.0.Final</version>

  <artifactId>hibernate-jpa-2.0-api</artifactId>
  <version>1.0.0.Final</version>

假设有两只猫(猫和它的伴侣有相同的小猫) 猫/猫的伴侣与它的小猫有关系,小猫的名字作为连接列(连接列上的 OneToMany 关系,获取类型为“eager”)

假设我想得到小猫名字为“大”的猫,为此,我可以用不同的方式编写 hql。

I.

hql.append("from Cat as cat ")
hql.append("where cat.kitten.name = 'big' ");

II.

hql.append("from Cat as cat inner join cat.kitten as kitten ")
hql.append("where kitten.name = 'big' ");

前面提到的 hql 在 cat 和它的小猫之间生成了一个内部连接,并且按预期工作。

但是,如果我想查询 kitten 中 cat 未加入 kitten 的属性(比如 location ),我可以编写 hql 如下:

III.

hql.append("from Cat as cat ")
hql.append("where cat.kitten.location = 'Chicago' ");

IV.

hql.append("from Cat as cat inner join cat.kitten as kitten ")
hql.append("where kitten.location = 'Chicago' ");

问题 1) III 和 IV 也按预期工作,但是,III 在 cat 和它的小猫之间生成笛卡尔/交叉连接,而没有在 hql 中提到的明确连接,而 IV 不是。这是为什么呢?

说,我想在 hql 中加入两个“不同”的对象 cat 和 mate(没有任何关联),它正在生成交叉连接。

例如,如果我说,

V.

hql.append("select cat ")
hql.append("from Cat as cat, Mate mate ")
hql.append("where cat.location = mate.location and mate.location = 'Chicago' ");

它生成交叉连接。

但是,如果我说,

VI.

hql.append("from Cat as cat ")
hql.append("where cat.location in ( select mate.location from Mate mate where mate.location = 'Chicago' ");

问题 2) 它不会生成交叉连接。但是,如果我必须使用两列怎么办。我需要使用两个 in 子句才能没有由 hql 生成的交叉连接。为什么一定要明确?或者如果可能的话,是否有休眠配置来避免交叉连接?

【问题讨论】:

    标签: hibernate jakarta-ee hql


    【解决方案1】:

    在第一种形式(I、III、V)中,表之间的连接条件在映射中定义(可能在&lt;one-to-many&gt;&lt;many-to.one&gt;&lt;one-to-one&gt;&lt;many-to-many&gt; 子句中)。在示例 I 中,您似乎定义了一个正确的,而在 III 和 V 中,您没有正确定义。

    在示例 II、IV 和 VI 中,您明确定义了连接(或子选择)。如果在 HQL 语句中有一个连接,Hibernate 总是在单个 SQL 语句中使用这个连接(如果连接是在映射中定义的,则不是这种情况 - Hibernate 通常更喜欢两个独立的选择(延迟加载仅在那时起作用)) .这在以下情况下很有用.

    如果我们要告诉你为什么 III 和 V 不能工作并产生笛卡尔积,那么你必须给我们表格的映射。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-31
      • 1970-01-01
      • 1970-01-01
      • 2017-10-01
      • 2011-09-25
      • 1970-01-01
      • 2014-05-12
      相关资源
      最近更新 更多