关于oracle分页不得不说的两个坑!

oracle分页的坑


项目用的mysql,有个需求需要连接人家的oracle。对方提供了视图,我们这边做了多数据源。做列表的时候分页突然就不香了,被oracle的分页安排的明明白白,满满当当!
希望我的踩坑经历能让更多人少走弯路,加快进度。

首先我从百度上找了一些关于oracle分页的博客,得出oracle分页实现代码:

select a.* from ( select t.*,rownum rowno from test t where rownum <= 10 ) a where a.rowno >= 1

基本原理就是利用子查询,然后传俩参数做个分页。本以为如此简单就完事了。放到项目里成功实现了分页,可以在我查询第二页第三页的时候我发现,第一页十条数据,第二页变成了九条,第三页变成了八条?越来越少,一页更比一页少。

debug。。。
第一页输出的sql:

select a.* from ( select t.*,rownum rowno from test t where rownum <= 10 ) a where a.rowno >= 1

第二页输出的sql:

select a.* from ( select t.*,rownum rowno from test t where rownum <= 10 ) a where a.rowno >= 2

第三页输出的sql:

select a.* from ( select t.*,rownum rowno from test t where rownum <= 10 ) a where a.rowno >= 3

看出来了吗?相信写过oracle分页的人已经知道问题出在哪了。如果你从来没写过oracle分页你一定是一脸懵逼的。

按mysql来说没错啊,一页查10个,一次一页没问题啊??
正是惯性思维导致了这个bug,oracle和mysql不一样。
在sql里面rownum 和rowno 参数代表的意义并不是页数和行数!!!!
而是开始节点和结束节点的意思!!!

rownum 是结束节点,rowno 是开始节点。以上三条sql改成如下你就明白了

#查询第一页的第1条到第10条
select a.* from ( select t.*,rownum rowno from test t where rownum <= 10 ) a where a.rowno >= 1

#查询第二页的第11条到20条
select a.* from ( select t.*,rownum rowno from test t where rownum <= 20 ) a where a.rowno >= 11

#查询第三页的第21条到30条
select a.* from ( select t.*,rownum rowno from test t where rownum <= 30 ) a where a.rowno >= 21

相信看到这里,你已经恍然大悟了吧,原来如此!!!

也就是说 这两个参数是动态传进来的!不是死的。

我自己也写了一个工具类提供大家参考:

public class OraclePageUtils {
    public static PageDomain oraclePage(){
   		//PageDomain是自己项目分页实体 不必在意
		PageDomain pageDomain = TableSupport.buildPageRequest();
		//关键在下面两行
        //oracle分页 开始节点
        //利用页数减1 乘10 再加1 刚好就是每次开始节点的值
        //比如第一页 (1-1)*10 +1 等于 10
        //比如第二页 (2-1)*10 +1 等于 11
        Integer oraclePageN = (pageDomain.getPageNum() - 1) * 10 +1;
        //oracle分页 结束节点
        //利用页数 乘 10 即为结束节点的值
        //比如第一页 1 * 10 等于 10
        //比如第二页 2 * 10 等于 10
        Integer oraclePageS = (pageDomain.getPageNum()) * 10;

        //算法规则完全符合上面三条sql的实现**加粗样式**
        pageDomain.setPageNum(oraclePageN);
        pageDomain.setPageSize(oraclePageS);
        return pageDomain;
		}
}
	

到这基本上Oracle分页的这个坑就说完了,不为别的,就为让别人少浪费点时间。

很欣赏马士兵老师的一句话:如果你有一天变强了,网上有人提问,能回答尽量回答!

另外 貌似还有一个坑不知道你们是否知道?
如果你用的mybatis和pageHelper做的分页,这个分页插件默认的参数貌似是pageNum和pageSize。 所以如果在做oracle分页的时候,要把这两个参数名重写!!重写!!重写!!! 写成啥都行,不一样就行!然后封到实体类面就行了!

希望这俩坑能帮到不少人吧!

我回去撸代码了!今天周末还在上班!MMP!!!

你可能感兴趣的:(JAVA_WEB)