繁体   English   中英

通过休眠标准自加入

[英]Self-join with Hibernate Criteria

无法找到一种在此类伪搜索索引表上添加条件的方式:

----------------------------------
| id | person_id | field | value |
----------------------------------
| 1  | 1         | fname  | John |
| 2  | 1         | lname  | Smith|
| 3  | 1         | zip    | 3000 |
| 4  | 2         | fname  | John |
| 5  | 2         | lname  | Doe  |
| 6  | 2         | zip    | 3000 |
----------------------------------

search_index表是个人实体的索引,该实体可以具有任意数量的任何种类的属性(当然,这是现实生活中问题的简化示例)。 一个“人”可以设置fname,另一个可以不设置,以此类推。 然后,客户端应用发送通用搜索请求fi((fname = John或fname = Karl)AND lname = Smith和zip = 3000)-这种东西。 因此,该系统相当通用-search_index中的可搜索字段列表以及任何类型的布尔搜索查询。 orderby也一样-可以是任何此可搜索字段。

在SQL中,我将执行以下操作:

SELECT si1.person_id from search_index si1
LEFT OUTER JOIN search_index si2 ON si1.id = si2.id
WHERE si2.field='lname'
AND si1.person_id in (select person_id from search_index where field = 'zip' and answer = '3000')
ORDER BY si2.value

按“ lname”订购找到的结果。

HQL可能是可行的,但是搜索条件是根据搜索字符串动态构建的,与动态HQL构造相比,Hibernate Criteria API使其更加容易。

  1. 为什么先左联接同一表,然后在WHERE子句中使用JOINED表? 这相当于一个INNER JOIN。

  2. 当您已经加入两个表时,为什么还要进行额外的子选择。

  3. 您为什么还要通过它们的ID联接两个表? 在您的查询中,您联接相同的行(因为您使用表ID作为联接条件)。

这个查询可以是您想要的吗?

SELECT si1.person_id 
from search_index si1
LEFT OUTER JOIN search_index si2 ON si1.person_id = si2.person_id AND si2.field='lname' 
WHERE si1.field = 'zip' and si1.answer = '3000'
ORDER BY si2.value

HQL和条件查询仅在导航现有关联时才可以为您提供帮助(自联接不是这种情况)。 因此,在这种情况下,您应该使用本机查询。

现在,返回您的查询。 您可以删除JOIN并将其编写为:

SELECT si1.person_id 
from search_index si1
WHERE si1.field='lname'
AND si1.person_id in (select person_id from search_index where field = 'zip' and answer = '3000')
ORDER BY si1.value

在这种情况下,您可以编写一个HQL查询:

select p.id
from SearchIndex si
join si.person p
where 
   si.field = :field1 and
   p.id in (select si2.person.id from SearchIndex si2 where si2.field = : field2 and answer = :answer)
order by si.value

更新

如果“ lname”字段仅对排序有用,那么您需要将子查询移到主查询中,然后在联接中移动“ lname”:

SELECT si1.person_id 
from search_index si1
where si1.field = 'zip' and si1.answer = '3000'
LEFT OUTER JOIN search_index si2 ON si1.person_id = si2.person_id AND si2.field='lname' 
ORDER BY si2.value

由于自连接语法,这需要本地查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM