【问题标题】:Inner join with select on HQL在 HQL 上使用 select 进行内部连接
【发布时间】:2012-08-02 11:59:15
【问题描述】:

我想用 HQL 做类似的事情:

SELECT *
FROM tableA a
INNER JOIN (select fieldA, sum(fieldB) as sum from tableB) b
ON a.fieldA = b.fieldA and a.fieldC = b.sum;

但这会报错:

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: (...

有什么方法可以使用 HQL 和 Hibernate 来实现这一点?

【问题讨论】:

  • 不,HQL 不允许在该位置进行内部选择。不过,您可能有办法改写它。

标签: java hibernate hql


【解决方案1】:

尝试原生 SQL 解决方法:

需要先导入这个:

import org.hibernate.SQLQuery;

然后在你的代码中的某个地方:

SQLQuery query = session.createSQLQuery(
    "SELECT * FROM tableA a
    INNER JOIN 
    (SELECT fieldA, sum(fieldB) as sum from tableB) b
    ON a.fieldA = b.fieldA and a.fieldC = b.sum"
);

more on this link
and HERE ( Joins in Hibernate Query Language)

【讨论】:

  • 是的,native 可以是一个解决方案,但我想要一个 HQL 解决方案,没有吗? :(
  • 刚刚尝试了SQL的解决方案,我不知道您可以使用query.addEntity(TableA.class)将结果设置为实体,否则结果将是一个对象数组。所以这种方式对我来说很完美。谢谢!
【解决方案2】:

你可以尝试用 HQL 做这样的事情:

String sqlText = 
        "select entityA 
         from EntityA entityA, EntityB entityB 
         where entityA.fieldA=entityB.fieldA 
         and entityA.fieldC=(select sum(entityB.fieldB) 
                             from EntityB entityB 
                             where entityB.fieldA=entityA.fieldA)"

Query query = session.createQuery(sqlText);

它应该与您的 sql 类似。关于您的陈述-我知道您不能在 HQL 中使用内部视图,因为它是面向对象的。

这是一个很好的article,关于 HQL 中的连接。

编辑:

根据 user1495181 的注释,上面的查询可以重写为(但我不确定):

String sqlText = 
        "select entityA 
         from EntityA entityA
         join entityA.entitiesB entityB
         Where entityA.fieldC=(select sum(entityB.fieldB) 
                             from EntityB entityB 
                             where entityB.fieldA=entityA.fieldA)"

但我更喜欢第一种变体,因为对我来说它更容易理解(尤其是对于曾经使用原生 SQL 的人来说)。

【讨论】:

  • 如果你在 A 和 B 之间有关系,你可以使用 join 来加入它们并将条件放在 where 中。
  • @user1495181 感谢您的编辑)。我错过了改变和在哪里。
  • 我喜欢你重写 hql 的方式,但我不确定它是否适用于我的情况(这比我的示例查询更复杂:P)。在这种情况下,使用本机 SQL 对我来说更好;)
【解决方案3】:

您不能使用 on 关键字定义连接。 Hibernate 知道如何根据您的映射进行连接。 如果您在 a 和 b 之间的映射中定义了一个关系,那么 hibernate 将根据您定义的关系进行连接。 如果您在 a 和 b 之间有关系,则在不使用 on 的情况下进行内部连接并将连接条件放在 where 子句中

【讨论】:

  • 您能详细说明一下吗?
  • 假设您有 Manager(1:m)Employe。它们之间的关系是在休眠映射(一对多)中定义的,所以当你想查询经理他们的雇员的薪水大于 100 时,你不需要像你在查询中那样指定关系带有连接 ...on 的 SQL 查询。使用休眠状态,您可以查询'从经理 m 加入 m.employee e where e。工资> 100(我没有指定如何进行连接。休眠通过映射知道它)。但是,如果您的连接没有在映射中定义(不是好的做法),那么您可以在 where 中进行显式连接:
猜你喜欢
  • 2012-11-04
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-19
  • 2014-05-31
  • 1970-01-01
相关资源
最近更新 更多