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 ...
随机推荐
- pat_1
2-0 2-1 #include <stdio.h> int main() { int inch,foot,cm; scanf("%d",&cm); foot= ...
- JS三元运算符
语法是 条件 ? 结果1 : 结果2; 问号(?)的前面是条件:后面跟着用冒号(:)分隔的结果1和结果2;满足条件时结果1否则结果2. 例子: var a=1; a>2?a:a=3; alert ...
- 用Total Commander替换windos默认资源管理器
用Total Commander替换windos默认资源管理器的方法 Total Commander(简称TC)是一个功能强大的资源管理器. TC本身没有自带的替换windows资源管理器的功能,就必 ...
- Matlab 仿真实现TI Instaspin 的Foc 逆Clarke变换和SVPWM
一直没搞明白TI 的Instaspin的SVPWM实现原理,最后只能在Matlab里仿真看看输出波形是不是和普通的SVPWM实现输出的波形一样,用M文件实现,下面是代码: clear all; the ...
- 新建Android工程没有自动生成R.JAVA,应该先升级下ADT
前几天非常郁闷,本来计划在Android上做个小东西,结果打开Eclipse新建工程,发现居然没有R.JAVA! 反复测试很多次,均未成功,最后试着升级了下ADT,结果搞定,在这里记下,下次遇到这样的 ...
- CKEditor扩展插件:自动排版功能
CKEditor是新一代的FCKeditor,是一个重新开发的版本.CKEditor是全球最优秀的网页在线文字编辑器之一,因其惊人的性能与可扩展性而广泛的被运用于各大网站. 如果还没接触过的可以看看, ...
- 站在巨人的肩膀上,C++开源库大全
程序员要站在巨人的肩膀上,C++拥有丰富的开源库,这里包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C++ Standard Library:是一系列 ...
- Java魔法堂:打包知识点之META-INF/MAINFEST.MF(转)
一.前言 通过执行形如 jar -cvf src.jar src 命令将多个.class文件打包成JAR包时,你会发现JAR包中除了src目录外还多了个MATE-INF/MAINFEST.MF,那是为 ...
- Chapter 13. Miscellaneous PerlTk Methods PerlTk 方法杂项:
Chapter 13. Miscellaneous PerlTk Methods PerlTk 方法杂项: 到目前为止,这本书的大部分章节 集中在特定的几个部件, 这个章节覆盖了方法和子程序 可以被任 ...
- [Leetcode][Python]46: Permutations
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 46: Permutationshttps://leetcode.com/pr ...