使用hibernate实现联合查询有哪些替代方法?我知道hibernate目前不支持联合查询,现在我看到建立联合的唯一方法是使用视图表.
另一种选择是使用普通的jdbc,但这样我就会放弃所有的示例/条件查询好东西,以及hibernate对表/列执行的hibernate映射验证.
你可以用 id in (select id from ...) or id in (select id from ...)
例如,而不是非工作
from Person p where p.name="Joe" union from Person p join p.children c where c.name="Joe"
你能做到的
from Person p where p.id in (select p1.id from Person p1 where p1.name="Joe") or p.id in (select p2.id from Person p2 join p2.children c where c.name="Joe");
至少使用MySQL,你将在以后遇到性能问题.相反,有时候让穷人加入两个查询更容易:
// use set for uniqueness Setpeople = new HashSet ((List ) query1.list()); people.addAll((List ) query2.list()); return new ArrayList (people);
通常两个简单的查询比一个复杂的查询更好.
编辑:
举一个例子,这里是从subselect解决方案得到的MySQL查询的EXPLAIN输出:
mysql> explain select p.* from PERSON p where p.id in (select p1.id from PERSON p1 where p1.name = "Joe") or p.id in (select p2.id from PERSON p2 join CHILDREN c on p2.id = c.parent where c.name="Joe") \G *************************** 1. row *************************** id: 1 select_type: PRIMARY table: a type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 247554 Extra: Using where *************************** 2. row *************************** id: 3 select_type: DEPENDENT SUBQUERY table: NULL type: NULL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL Extra: Impossible WHERE noticed after reading const tables *************************** 3. row *************************** id: 2 select_type: DEPENDENT SUBQUERY table: a1 type: unique_subquery possible_keys: PRIMARY,name,sortname key: PRIMARY key_len: 4 ref: func rows: 1 Extra: Using where 3 rows in set (0.00 sec)
最重要的是,1.row不使用任何索引并考虑200k +行.坏!执行此查询需要0.7秒,因为两个子查询都在毫秒内.
使用VIEW.可以使用实体名称将相同的类映射到不同的表/视图,因此您甚至不会有太多重复.在那里,做到这一点,工作正常.
简单的JDBC有另一个隐藏的问题:它不知道Hibernate会话缓存,所以如果某些东西被缓存到事务结束并且没有从Hibernate会话中刷新,那么JDBC查询将无法找到它.有时可能非常令人费解.
我不得不同意弗拉基米尔的观点.我也考虑过在HQL中使用UNION而无法找到解决方法.奇怪的是,我可以找到(在Hibernate常见问题解答中)UNION不受支持,与UNION标记为"已修复"的错误报告,人们的新闻组称这些声明将在UNION被截断,而其他人报道的新闻组也有效好了...经过一天的捣乱,我最终将我的HQL移植回纯SQL,但在数据库中的View中执行它将是一个不错的选择.在我的例子中,查询的一部分是动态生成的,所以我不得不在代码中构建SQL.