使用hibernate实现联合查询,我必须采取什么替代方法?我知道hibernate状态目前不支持联合查询,现在我看到的建立联合的唯一方法是使用视图表。
另一个选择是使用普通的jdbc,但是这样一来,我将失去所有示例/条件查询功能,以及hibernate对表/列执行的hibernate映射验证。
另一个选择是使用普通的jdbc,但是这样一来,我将失去所有示例/条件查询功能,以及hibernate对表/列执行的hibernate映射验证。使用VIEW。可以使用实体名称将相同的类映射到不同的表/视图,因此你甚至不需要太多重复。在那里,这样做就可以了。
普通的JDBC还有另一个隐藏的问题:它不知道Hibernate会话缓存,因此,如果在事务结束之前缓存了某些内容,并且没有从Hibernate会话中清除该内容,则JDBC查询将找不到它。有时候可能会很令人困惑。
你可以用 id in (select id from ...) or id in (select id from ...)
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 Set<Person> people = new HashSet<Person>((List<Person>) query1.list()); people.addAll((List<Person>) query2.list()); return new ArrayList<Person>(people);
进行两个简单的查询通常比处理一个复杂的查询要好。
编辑:
举个例子,这是子选择解决方案的结果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.行不使用任何索引,而是考虑200k +行。坏!该查询的执行时间为0.7s,其中两个子查询都以毫秒为单位。