hibernate的 HQL是不支持union语句的。所以,我们只能使用原生态SQL语句来做~
问题是,不但要查出语句,还要封装成对象供应页面显示,这时,我们可以使用HQL的addScalar和setResultTransformer 来达到效果!
这就是所谓的标量查询,实际上,如果我们查询的两个表字段都一样对象一样的情况下,可以直接使用addEntity来把字段封装对象。在这里,
一个问题之一就是:union合并的字段不是都是来自同一个表。
StringBuffer sb = new StringBuffer(); sb.append("( select sc.SCID as scid , sc.XN as xn , sc.XQ as xq , sc.XKKH as xkkh , sc.KCMC as kcmc , "); sb.append(" sc.JXDW as jxdw , sc.XH as xh , sc.XM as xm , sc.XB as xb , sc.BJ as bj , sc.STATUS as status , "); sb.append(" sc.QXZT as qxzt from STUDENTCHECK sc "); sb.append(" where 1=1 and (sc.XN like ? ) "); sb.append(" and sc.XQ=? "); sb.append(" and sc.XKKH=? )"); sb.append(" union "); sb.append("( select (case when cv.cvid=-1000000 then cv.cvid else null end) as scid , "); sb.append(" substr(s.term,6,4) as xn , to_number(substr(s.term,11,1)) as xq , sc.xkkh as xkkh , "); sb.append(" c.coursename as kcmc , stu.xy as jxdw , stu.XH as xh , stu.XM as xm , stu.xb as xb , "); sb.append(" stu.xzb as bj , (case when cv.cvid = -1000000 then cv.cvid else 1 end) as status , "); sb.append(" (case when cv.cvid = -1000000 then cv.cvid else 0 end) as qxzt "); sb.append(" from CVARIABLE cv , SEMESTER s , STUBASICINFO stu , COURSE c,SCOURSE sc "); sb.append(" where cv.SID = s.SID and cv.SCID = sc.SCID and sc.xkkh = c.coursecode and cv.XH = stu.XH and 1=1 ");
sb.append(" and (stu.xh not in (select sc.xh from STUDENTCHECK sc where stu.xh= sc.xh))"); sb.append(" and (s.TERM like ? ) "); sb.append(" and sc.XKKH = ? ");
需要强制转换。addScalar和setResultTransformer 的好处是,不需要所有的字段都要强制转换成对象。而,addEntiry必须是对象的所有对象,比如,sc.*
我们可以这样做。
Query query = session.createSQLQuery(hql) .addScalar("scid",Hibernate.LONG) .addScalar("xn", Hibernate.STRING) .addScalar("xq", Hibernate.INTEGER) .addScalar("xkkh",Hibernate.STRING) .addScalar("kcmc",Hibernate.STRING) .addScalar("jxdw",Hibernate.STRING) .addScalar("xh",Hibernate.STRING) .addScalar("xm",Hibernate.STRING) .addScalar("xb",Hibernate.INTEGER) .addScalar("bj",Hibernate.STRING) .addScalar("status",Hibernate.INTEGER) .addScalar("qxzt",Hibernate.INTEGER) .setResultTransformer(Transformers.aliasToBean(Studentcheck.class));
例子:
(select * from Article where type=1 order by date desc limit 10) union (select * from Article where type=3 order by date desc limit 10)
使用union最好把两个子查询都使用()括起来。
如果想对整体的联合结果进行排序分页的话则直接把order或者limit写到总执行语句的最后即可,当然这也是支持的数据库才行。
现在的问题之二:不但要union合并而且还要排序和分页
但是问题又来了,你使用的是什么数据库?
如果你使用Oracle,那么没办法,你遇到麻烦了!Oracle不和别的数据库一样,limit的使用在Oracle是不能使用的。
这里主要针对的Oracle的union,order by,分页共存的问题
只能充分使用Oracle的rowid 和rownum变量来达到我们的想要的效果。
网络上对于Oracle模仿limit分页的方法:
select * from a_matrix_navigation_map where rowid not in(select rowid from a_matrix_navigation_map where rownum<=0) and rownum<=10 第二种: SELECT * FROM ( SELECT A.*, rownum r FROM ( SELECT * FROM a_matrix_navigation_map ) A WHERE rownum <= 10 ) B WHERE r > 0 第三种 SELECT * FROM table WHERE ROWNUM<101; minus SELECT * FROM table WHERE ROWNUM<91;
这是实现了第二方式的分页的问题:
代码如下:
select t2.* from (select t1.*,rownum rnum from ((select sc.SCID as scid, sc.XN as xn, sc.XQ as xq, sc.XKKH as xkkh, sc.KCMC as kcmc, sc.JXDW as jxdw, sc.XH as xh, sc.XM as xm, sc.XB as xb, sc.BJ as bj, sc.STATUS as status, sc.QXZT as qxzt from JISUANJI.STUDENTCHECK sc where 1=1 and ( sc.XN like '%2014%' ) and sc.XQ=2 and sc.XKKH=34567896 ) union ( select (case when cv.cvid=-1000000 then cv.cvid else null end) as scid, substr(s.term,6,4) as xn, to_number(substr(s.term,11,1)) as xq, sc.xkkh as xkkh, c.coursename as kcmc, stu.xy as jxdw, stu.XH as xh, stu.XM as xm, stu.xb as xb, stu.xzb as bj, (case when cv.cvid=-1000000 then cv.cvid else 1 end) as status, (case when cv.cvid=-1000000 then cv.cvid else 0 end) as qxzt from JISUANJI.CVARIABLE cv, JISUANJI.SEMESTER s, JISUANJI.SCOURSE sc, JISUANJI.STUBASICINFO stu, JISUANJI.COURSE c where cv.SID=s.SID and cv.SCID=sc.SCID and sc.xkkh=c.coursecode and cv.XH=stu.XH and 1=1
and (stu.xh not in (select sc.xh from STUDENTCHECK sc where stu.xh= sc.xh)) and ( s.TERM like '%2013-2014-2%' ) and sc.XKKH=34567896 and ( stu.XZB like '%计算机2班%' or stu.XZB like '%计算机2班%' ))) t1)t2 where t2.rnum>=1 and t2.rnum<=10 order by xh desc