解决hibernate 中oracle排序分页错乱问题

2014/06/24 3062点热度 0人点赞 0条评论

    在使用SHH进行J2EE轻量级项目开发时,用到了oracle11g的数据库,但是在对表中的数据进行排序分页时,有时会莫名其妙的出现排序错乱,翻页后数据显示重复的问题。开始以为是hibernate的问题,跟踪代码将hibernate生成的sql语句输出到控制台然后在PL/SQL中执行,发现生成的sql语句有点问题,执行的结果数据集根本就不对,就是Hibernate的问题,但是这个问题很容易就被发现,毕竟hibernate作为开源项目,并且应用广泛,如果是BUG,早就应该被fix掉。后来仔细一想,还是认为是oracle数据库在排序的方式上与sql server等数据库有区别,在oracle中用排序分页,比如第3页的数据, 需要用到rownum函数,但是rownum函数非常特别,它并不像sql server中的top函数好用。比如我要取PR_PROJECTS表中按字段created排序的第3页(10条数据/页)数据,按照正常的理解应该这样写SQL,如下:

  select
        * 
    from
        ( select
            row_.*,
            rownum rownum_ 
        from
            ( select p.projectName,
       p.id,
       p.projectCode,
       p.companyName,
       p.stageName,
       p.clusterName,
       p.optStatue,
       p.optflag
  from PR_PROJECTS p
 where p.delStatue = 0
   and (p.companyCode = '0032016' or p.companyCode = '0032028' or
       p.companyCode = '0032020' or p.companyCode = '0032032')
 order by p.created desc) row_
 where
            rownum <= 30
        ) 
    where
        rownum_ > 20

也就是说先排序了后,取出前面的20条数据,然后再从20条数据中取出后10条数据,这样就完成了排序分页的功能。是不是很郁闷,郁闷的问题还在后面,对于created字段来说,数据重复的可能性不大,可刚才写的排序分页后的数据不对,第三页经常出现第二页的数据,百思不得其解,没办法,GOOGLE一下,发现oracle要取排序后的某部分记录,最好是在排序字段中包含主键或不会重复的字段,这样排序分页的问题就迎刃而解。我查看了下我created字段,发现有很多重复的值,最终我采用了在排序表达式后加入了主键(p.id)的排序,问题得以解决。  

yxkong

这个人很懒,什么都没留下

文章评论