hql中or的用法(代替union)
hql中不支持union和unionAll关键字因为在查询出的结果集中无法进行排序。代替union起到相同作用的 是or关键字。在构造hql时考虑使用or代替union产生多个结果集的组合。
详解如下(转载):
经过百度,google知道hibernate中hql是不支持union的,所以只能借助native sql了。背景如下:一年前写了一个hql:
原来代码
- String countHql2 = "select count(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)";
- 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
- 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
- + " UNION SELECT pr.id FROM project pr,project_bookmark b WHERE pr.id=b.project_id AND b.uid=" + userId + ") AS temp";
- 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 + ")"
- + "UNION"
- + "(SELECT {p.*} FROM project p,project_bookmark b WHERE p.id=b.project_id AND b.uid=" + userId + ")LIMIT " + (pageIndex - 1) * maxPerPage + "," + maxPerPage;
- SQLQuery query = this.getSession().createSQLQuery(sql1);
- Integercount=Integer.valueOf(((BigInteger)query.uniqueResult()).toString());
- SQLQuery query2 = this.getSession().createSQLQuery(sql2);
- query2.addEntity("p", Project.class);
- 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时
- 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 + ")"
- + "UNION"
- + "(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)的更多相关文章
- hql中in的用法
平时经常用Hibernate,由于习惯表间不建立关联,所以HQL查询时候经常要用in语句. 由于表间没有建立外键的关联关系所以使用in是最常见的代替使用对象po中的set. 但是在写hql时如果在ne ...
- SQL中MINUS的用法与UNION的用法
一:MINUS指令 其是运用在两个 SQL 语句上.它先找出第一个 SQL 语句所产生的结果,然后看这些结果有没有在第二个 SQL语句的结果中.如果有的话,那第一个SQL结果数据就被去除,而不会在最后 ...
- Oracle 中 decode 函数用法
Oracle 中 decode 函数用法 含义解释:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下:IF 条件=值1 THEN RETURN(翻译 ...
- HQL查询——HQL查询的基本用法
HQL查询--HQL查询的基本用法 1.HQL语法类似于SQL语法,但是需要注意的是,HQL是一种完全面向对象的查询语言.SQL语言操作的对象是数据表.列等数据库对象,而HQL语言的操作对象是类.实例 ...
- oracle中to_date详细用法示例(oracle日期格式转换)
这篇文章主要介绍了oracle中to_date详细用法示例,包括期和字符转换函数用法.字符串和时间互转.求某天是星期几.两个日期间的天数.月份差等用法 TO_DATE格式(以时间:2007-11-02 ...
- [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法
一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...
- C#中string.format用法详解
C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...
- SQL中distinct的用法
SQL中distinct的用法 1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...
- jQuery中Animate进阶用法(一)
jQuery中animate的用法你了解多少呢?如果仅仅是简单的移动位置,显示隐藏,哦!天哪你在浪费资源!因为animate太强大了,你可以有很多意想不到的用法!让我们一起研究一下吧~~ 首先要了解j ...
随机推荐
- PPT 制作必备工具
1.图标 http://www.easyicon.net/ http://ico.58pic.com/ http://www.iconpng.com/ 2.字体 http://www.qiuziti. ...
- golang Date format
package main import ( "fmt" "time" ) // @link https://golang.org/pkg/time/ func ...
- python 2.6升级到2.7
CentOS 6.5上安装的python版本是2.6.6,不能满足我运行软件的要求,所以对python进行升级. 原以为这也就是安装个软件的事儿,在我求稳搜索一下了之后发现,也并不是那么单纯简单. 下 ...
- ListView的使用——聊天窗口
一.步骤 1.在layout创建两个布局,分别是自己的回答条,和对方的回答条. 2.创建ChatMessage这个类,成员变量有头像地址.聊天内容.所属类型(假设1表示对方,2表示自己). 3.创建C ...
- eclipse优化配置
-startup plugins/org.eclipse.equinox.launcher_1..jar --launcher.library plugins/org.eclipse.equinox. ...
- Storm Esper
https://github.com/hellojinjie https://github.com/tomdz/storm-esper https://github.com/jayway/awaiti ...
- 【N年前的文章脑补:HttpHandler HttpModule入门篇】
HttpHandler HttpModule入门篇 ASP.Net处理Http Request时,使用Pipeline(管道)方式,由各个HttpModule对请求进行处理,然后到达 HttpHand ...
- TCP 协议三次握手过程解析带实例
TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...
- 数据结构multiset hdu-2275-Kiki & Little Kiki 1
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2275 题目意思: 有两种操作: 1.push a 把a放进数组里. 2.pop a 输出不超过a的最 ...
- python list求交集
方法一: a=[1,2,3] b=[1,3,4] c=list(set(a).intersection(set(b))) print c #[1,3] 这种方法是先把list转换为set,再用set求 ...