Hibernate Union的替代品

Mig*_*ing 55 java sql union hibernate

使用hibernate实现联合查询有哪些替代方法?我知道hibernate目前不支持联合查询,现在我看到建立联合的唯一方法是使用视图表.

另一种选择是使用普通的jdbc,但这样我就会放弃所有的示例/条件查询好东西,以及hibernate对表/列执行的hibernate映射验证.

sfu*_*ger 68

你可以用 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"
Run Code Online (Sandbox Code Playgroud)

你能做到的

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");
Run Code Online (Sandbox Code Playgroud)

至少使用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);
Run Code Online (Sandbox Code Playgroud)

通常两个简单的查询比一个复杂的查询更好.

编辑:

举一个例子,这里是从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)
Run Code Online (Sandbox Code Playgroud)

最重要的是,1.row不使用任何索引并考虑200k +行.坏!执行此查询需要0.7秒,因为两个子查询都在毫秒内.

  • 如果你想要分页,你不能使用两个子查询,不是吗? (3认同)
  • 来自我的 +1。尽管执行两个简单查询通常比执行一个复杂查询要好,但执行使用适当索引的单个查询通常更好。 (2认同)

Vla*_*hev 30

使用VIEW.可以使用实体名称将相同的类映射到不同的表/视图,因此您甚至不会有太多重复.在那里,做到这一点,工作正常.

简单的JDBC有另一个隐藏的问题:它不知道Hibernate会话缓存,所以如果某些东西被缓存到事务结束并且没有从Hibernate会话中刷新,那么JDBC查询将无法找到它.有时可能非常令人费解.

  • 当你有二级缓存时,更令人费解的是,但是从应用程序的其他部分使用普通的JDBC(比如用于报告). (2认同)

Cod*_*ike 6

我不得不同意弗拉基米尔的观点.我也考虑过在HQL中使用UNION而无法找到解决方法.奇怪的是,我可以找到(在Hibernate常见问题解答中)UNION不受支持,与UNION标记为"已修复"的错误报告,人们的新闻组称这些声明将在UNION被截断,而其他人报道的新闻组也有效好了...经过一天的捣乱,我最终将我的HQL移植回纯SQL,但在数据库中的View中执行它将是一个不错的选择.在我的例子中,查询的一部分是动态生成的,所以我不得不在代码中构建SQL.