HQL留下了非关联实体的连接
我有两个实体, A
和B
他们是相关的,但我不想将关系映射添加到豆。
我们如何使用HQL或条件使用A
和B
之间A
左外连接 ?
有一些解决方法可用于此,
- 按照此处所述使用Native SQL。
- 添加一个关系并使用从A中select一个左连接ab 。
- 我们可以在HQL中做一个内部连接 select * from A a,B b where a.some = b.some
我总是回去这两个选项,有没有其他的select呢? 或者这在不可能?
目前,使用HQLjoinwhere子句中无关类的theta样式只支持内连接。
支持这种情况的外连接的请求 目前是第三次投票增强,但我不认为这个特性将在近端特性中实现,因为它需要首先重新实现当前的基于ANTLER的查询parsing器这似乎是IMO的一个巨大的任务。
如果您坚持使用HQL来执行左连接而不添加A和B之间的关系,则可以使用选项3先执行内连接,然后使用以下HQL
from A a where a.some not in ( select b.some from B)
找出所有不能joinB的A,并以编程方式结合结果。
更新
从版本5.1.0开始, HHH-16(对不相关类的显式连接)是固定的,我们应该能够join不相关的实体。
正如Ken Chan所说,你不能直接在一个HQL查询中完成。
关于你的三种可能性:
- 原生SQL:不推荐。 外连接的语法在不同的数据库之间是完全不同的。
- 添加一个关系:这就是我会做的。 它不会花费太多的代码或内存,并且可以快速编程。
- 内部连接:如果关系确实是数据库中的外部连接,则不起作用(缺less行)。
如果由于任何特殊的原因你不想添加关系,你可以将查询拆分为两个单独的查询,并在java中手动join结果,例如:
Query qa = session.createQuery("from A a"); List la = qa.list(); Query qb = session.createQuery("select distinct b.* from B b, A a where a.some=b.some"); List lb = qb.list(); Map bMap = new HashMap(); for (B b : lb) { bMap.put(b.getId(), b); } /* example with for loop */ for (A a : la) { B b = bMap.get(a.getForeignKeyForB()); /* now you have A a and the outer joined B b and you can do with them what you want */ ... }
该解决scheme在执行时间和内存方面与数据库中的外连接(解决scheme2)具有(几乎)相同的成本。 这只是一个更多的Java代码。
(该解决scheme与Ken Chan提出的解决scheme类似,但是避免了“不在”和内部select,这两者在数据库中都是低效的)。
大胆的声明:你不能。
为什么? JPQL(和HQL)期望实体之间的path,以join它们。
我通常在这样的情况下做的(首选):
- 关联实体。
- 获取您需要的数据以编程方式组装结果。
- 您已经提到的三个选项中的一个或三个。
如果你知道每个A有最多1 B,你也可以使用子查询。
例如:
select a, (select b from B b where b.some = a.some) from A a
如果您知道至less存在1 B,则也可以使用以下查询,但不build议这样做,因为它是黑客行为:
select a, (select b4 from B b4 where b4=b and b4.some=a.some) from A a, B b where a.some=b.some or (a.some not in (select b2.some from B b2) and b.id = (select min(b3.id) from B b3))