hql中不支持union和unionAll关键字因为在查询出的结果集中无法进行排序。代替union起到相同作用的 是or关键字。在构造hql时考虑使用or代替union产生多个结果集的组合。

详解如下(转载):

经过百度,google知道hibernate中hql是不支持union的,所以只能借助native sql了。背景如下:一年前写了一个hql:

原来代码

  1. String countHql2 = "select count(distinct p) from Project as p,CommentSimple as c,ProjectBookmark as b where ("
  2. + "c.owner.id=? and p.id=c.targetId and c.targetType=500) or (b.user.id=? and p.id=b.project.id)";
  3. String hql2 = "select distinct p from Project as p,CommentSimple as c,ProjectBookmark as b where ( "+ "c.owner.id=? and p.id=c.targetId and c.targetType=500) or (b.user.id=? and p.id=b.project.id)";

主要是找出某个人所有评论过或收藏过的项目。简单表结构如下:

project:id owner_id(用户id)保存项目的基本信息

project_bookmark:uid(用户id),project_id(收藏的项目的id),owner_id(收藏者的id)

comment_simple:target_type(保存对某种对象的评论,值为500时表示的对项目的评论),target_id(保存对某种对象的评论,值为该对象的id),project_id(项目的id),owner_id(评论者的id)

由于这个sql执行时所建的索引无法使用,而且还造成了三个表连接会有大量的无效的查询以及重复结果,最后还得要distinct可以想象执行的效率。

只好改用union来重写,需要用到hibernate的native sql,经过努力终于找到可以用union找出整个对象以及在配置文件中与该对象有关系的对象的方法。

与其说是找出来的,不如说是试出来的,代码如下:

union

  1. String sql1 = "SELECT COUNT(*) FROM(SELECT p.id FROM project p,comment_simple c WHERE p.id=c.target_id AND c.target_type=500 AND c.uid=" + userId
  2. + " UNION SELECT pr.id FROM project pr,project_bookmark b WHERE pr.id=b.project_id AND b.uid=" + userId + ") AS temp";
  3. String sql2 = "(SELECT {p.*} FROM project p,comment_simple c WHERE p.id=c.target_id AND c.target_type=500 AND c.uid=" + userId + ")"
  4. + "UNION"
  5. + "(SELECT {p.*} FROM project p,project_bookmark b WHERE p.id=b.project_id AND b.uid=" + userId + ")LIMIT " + (pageIndex - 1) * maxPerPage + "," + maxPerPage;
  6. SQLQuery query = this.getSession().createSQLQuery(sql1);
  7. Integercount=Integer.valueOf(((BigInteger)query.uniqueResult()).toString());
  8. SQLQuery query2 = this.getSession().createSQLQuery(sql2);
  9. query2.addEntity("p", Project.class);
  10. List<Project> list = query2.list();

sql1符合条件的项目的总数。sql2求出符合条件项目的某一页。

要注意的是:sql2中{p.*}要写成一样的。

简而言之:select {a.*} from A a where ... union select {a.*} from A a where...

如果还要排序的话sql2换成sql3:

需要order by时

  1. String sql3 = "(SELECT {p.*},p.created FROM project_hz p,comment_simple c WHERE p.id=c.target_id AND c.target_type=500 AND c.uid=" + userId + ")"
  2. + "UNION"
  3. + "(SELECT {p.*} ,p.created FROM project_hz p,project_bookmark b WHERE p.id=b.project_id AND b.uid=" + userId + ") ORDER BY created LIMIT " + (pageIndex - 1) * maxPerPage + "," + maxPerPage;

要注意的是p.created(需要排序的那个字段) 要个别标出,因为hibernate在转换为sql是会写成 select created as ...所以排序时将不起作用,需要我们自己标出。

这里只是找出了一个解决方案,因为对hibernate的调优不是特别熟悉这样做会不会造成另外不好的影响就不清楚了,如果有高手看到有什么问题,或者有更好的方法。请不吝赐教!!

hql中or的用法(代替union)的更多相关文章

  1. hql中in的用法

    平时经常用Hibernate,由于习惯表间不建立关联,所以HQL查询时候经常要用in语句. 由于表间没有建立外键的关联关系所以使用in是最常见的代替使用对象po中的set. 但是在写hql时如果在ne ...

  2. SQL中MINUS的用法与UNION的用法

    一:MINUS指令 其是运用在两个 SQL 语句上.它先找出第一个 SQL 语句所产生的结果,然后看这些结果有没有在第二个 SQL语句的结果中.如果有的话,那第一个SQL结果数据就被去除,而不会在最后 ...

  3. Oracle 中 decode 函数用法

    Oracle 中 decode 函数用法 含义解释:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下:IF 条件=值1 THEN RETURN(翻译 ...

  4. HQL查询——HQL查询的基本用法

    HQL查询--HQL查询的基本用法 1.HQL语法类似于SQL语法,但是需要注意的是,HQL是一种完全面向对象的查询语言.SQL语言操作的对象是数据表.列等数据库对象,而HQL语言的操作对象是类.实例 ...

  5. oracle中to_date详细用法示例(oracle日期格式转换)

    这篇文章主要介绍了oracle中to_date详细用法示例,包括期和字符转换函数用法.字符串和时间互转.求某天是星期几.两个日期间的天数.月份差等用法 TO_DATE格式(以时间:2007-11-02 ...

  6. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

  7. C#中string.format用法详解

    C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...

  8. SQL中distinct的用法

    SQL中distinct的用法   1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...

  9. jQuery中Animate进阶用法(一)

    jQuery中animate的用法你了解多少呢?如果仅仅是简单的移动位置,显示隐藏,哦!天哪你在浪费资源!因为animate太强大了,你可以有很多意想不到的用法!让我们一起研究一下吧~~ 首先要了解j ...

随机推荐

  1. PPT 制作必备工具

    1.图标 http://www.easyicon.net/ http://ico.58pic.com/ http://www.iconpng.com/ 2.字体 http://www.qiuziti. ...

  2. golang Date format

    package main import ( "fmt" "time" ) // @link https://golang.org/pkg/time/ func ...

  3. python 2.6升级到2.7

    CentOS 6.5上安装的python版本是2.6.6,不能满足我运行软件的要求,所以对python进行升级. 原以为这也就是安装个软件的事儿,在我求稳搜索一下了之后发现,也并不是那么单纯简单. 下 ...

  4. ListView的使用——聊天窗口

    一.步骤 1.在layout创建两个布局,分别是自己的回答条,和对方的回答条. 2.创建ChatMessage这个类,成员变量有头像地址.聊天内容.所属类型(假设1表示对方,2表示自己). 3.创建C ...

  5. eclipse优化配置

    -startup plugins/org.eclipse.equinox.launcher_1..jar --launcher.library plugins/org.eclipse.equinox. ...

  6. Storm Esper

    https://github.com/hellojinjie https://github.com/tomdz/storm-esper https://github.com/jayway/awaiti ...

  7. 【N年前的文章脑补:HttpHandler HttpModule入门篇】

    HttpHandler HttpModule入门篇 ASP.Net处理Http Request时,使用Pipeline(管道)方式,由各个HttpModule对请求进行处理,然后到达 HttpHand ...

  8. TCP 协议三次握手过程解析带实例

    TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...

  9. 数据结构multiset hdu-2275-Kiki & Little Kiki 1

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2275 题目意思: 有两种操作: 1.push a 把a放进数组里. 2.pop a 输出不超过a的最 ...

  10. python list求交集

    方法一: a=[1,2,3] b=[1,3,4] c=list(set(a).intersection(set(b))) print c #[1,3] 这种方法是先把list转换为set,再用set求 ...