一尘不染

Hibernate Union替代方案

java

使用hibernate实现联合查询,我必须采取什么替代方法?我知道hibernate状态目前不支持联合查询,现在我看到的建立联合的唯一方法是使用视图表。

另一个选择是使用普通的jdbc,但是这样一来,我将失去所有示例/条件查询功能,以及hibernate对表/列执行的hibernate映射验证。


阅读 494

收藏
2020-03-19

共2个答案

一尘不染

使用hibernate实现联合查询,我必须采取什么替代方法?我知道hibernate状态目前不支持联合查询,现在我看到的建立联合的唯一方法是使用视图表。

另一个选择是使用普通的jdbc,但是这样一来,我将失去所有示例/条件查询功能,以及hibernate对表/列执行的hibernate映射验证。使用VIEW。可以使用实体名称将相同的类映射到不同的表/视图,因此你甚至不需要太多重复。在那里,这样做就可以了。

普通的JDBC还有另一个隐藏的问题:它不知道Hibernate会话缓存,因此,如果在事务结束之前缓存了某些内容,并且没有从Hibernate会话中清除该内容,则JDBC查询将找不到它。有时候可能会很令人困惑。

2020-03-19
一尘不染

你可以用 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,其中两个子查询都以毫秒为单位。

2020-03-19