zoukankan      html  css  js  c++  java
  • [数据库]Oracle和mysql中的分页总结

    Mysql中的分页
    物理分页
    •在sql查询时,从数据库只检索分页需要的数据
    •通常不同的数据库有着不同的物理分页语句
    •mysql物理分页,采用limit关键字
    •例如:检索11-20条 select * from user limit 10,10 ;

     

    * 每次只查询10条记录.当点击下一页的时候,查询数据库,查询后10条.

    * 优点:如果数据量非常大,不会导致内存溢出.

    * 缺点:每次都与数据库进行交互.

    * 分页一般采用数据库的sql语句完成分页查询.

    * MYSQL分页:使用limit关键字.

    * Oracle分页:使用rownum    SQLServer分页:使用top关键字.

    * select * from customer limit a,b;

    * 参数a:代表从那条记录开始,初始值是0.

    * 参数b:查询长度.

     

    * 分页关系:

    page(当前页数)            limit(每页显示条数)           start(从哪开始的)

    1                        10                          0

    2                        10                          10

    3                        10                          20

     

    ***** start = (page - 1) * limit;

     

    * 向后台传递值:当前页数.

    * 后台向页面显示数据:currPage(当前页数)、List<Customer>、totalPage(总页数.需要通过总记录数进行计算.)、totalCount(总记录数)、limit(每页显示的记录数).

    * 将这些参数进行封装.封装到一个JavaBean中. 用request域存取JavaBean.

     ====================================华丽丽的分割线================================================

    Oracle中的分页:

    Oracle中分页用rownum;

    rownum的特点现象:
     1 SQL> select rownum,ename from emp;
     2 
     3 ROWNUM ENAME
     4 ---------- ----------
     5 1 SMITH
     6 2 ALLEN
     7 3 WARD
     8 4 JONES
     9 5 MARTIN
    10 6 BLAKE
    11 7 CLARK
    12 8 SCOTT
    13 9 KING
    14 10 TURNER
    15 11 ADAMS
    16 12 JAMES
    17 13 FORD
    18 14 MILLER

     如果在加上order by排序的条件限制

     1 SQL> select rownum ,ename,sal from emp order by sal desc;
     2 
     3     ROWNUM ENAME             SAL
     4 ---------- ---------- ----------
     5          9 KING             5000
     6         13 FORD             3000
     7          8 SCOTT            3000
     8          4 JONES            2975
     9          6 BLAKE            2850
    10          7 CLARK            2450
    11          2 ALLEN            1600
    12         10 TURNER           1500
    13         14 MILLER           1300
    14          3 WARD             1250
    15          5 MARTIN           1250
    16         11 ADAMS            1100
    17         12 JAMES             950
    18          1 SMITH             800

    加上order by 之后rownum 依旧没有变化,说明rownum是基于原始表emp进行排序的 ,固定住了,所以如下使用rownum<=3 来取得Top3是错误的:

     1 SQL> select rownum,empno,ename,sal
     2  from emp
     3  where rownum<=3
     4  order by sal desc;
     5 
     6     ROWNUM      EMPNO ENAME             SAL                                                                                                           
     7 ---------- ---------- ---------- ----------                                                                                                           
     8       7499 ALLEN            1600                                                                                                           
     9       7521 WARD             1250                                                                                                           
    10       7369 SMITH             800

     为什么Oracle中的rownum行号不变?

    解释:

    在Oracle中分为标准表,临时表,索引表...

    1 SQL> --标准表,临时表,索引表
    2 SQL> --create global temporary table *****
    3 SQL> --临时表:基于会话 基于事务
    4 SQL> --特点:当会话或者事务结束的时候,表中的数据自动删除

    创建临时表用create global temporary table 临时表可以基于会话,也可以基于事务.

    特点:当会话或者事务结束的时候,表中的数据自动删除.退出会话,或者退出事务表中的删除就删除了.

    比如:公司财务会做很多报表.中间的结果可以保存到临时表中.最后也不需要手动删除.

    临时表有两种方式创建,一个是手动,一个是Oracle自动创建临时表.

    自动创建临时表最典型的是排序,order by....

    order by...之后Oracle会自动创建一个临时表,保存的是排好序之后的数据.

    我们最终看到的排好序的是临时表中的数据.

    但是行号永远来按照原来的表来生成,只要原来的表来生成,只要原来的表内容没有变,行号就不变....这就解释了为什么行号不变...

     

    1 SQL> /*
    2 SQL> 注意的问题
    3 SQL> 1. rownum永远按照默认的顺序生成
    4 SQL> 2. rownum只能使用< <=; 不能使用> >=
    5 SQL> */

    rownum只能使用< <=; 不能使用> >= 如下使用>=就报错.

    这个和行号的生成原理有关系,OracleMysql都是基于行的行式数据库,nosql数据库都是基于列的.

    Oracle这样的行式数据库中rownum永远从1开始,取了第1行才能去第2...取了第2行才能取第三行....

     rownum>=5 所以这个条件永远为假,前面的4个都没有取.  rownum<=8 这个条件可以.

     如果在sql中使用'rownum >'

    SQL> --分页
    SQL> select rownum,empno,ename,sal
      2  from emp
      3  where rownum>=5 and rownum<=8;
    
    未选定行
    
    SQL> select rownum,empno,ename,sal
      2  from emp
      3  where rownum>=5;
    
    未选定行

    解决方法是:

    --oracle分页
    SQL>  select *
      2   from      (select rownum r,e1.*
      3      from (select * from emp order by sal) e1
      4      where rownum <=8
      5     )
      6   where r >=5;
    
             R      EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
    ---------- ---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
             5       7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
             6       7934 MILLER     CLERK           7782 23-1月 -82           1300                    10
             7       7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
             8       7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30

    详细的分析过程因为博客园 编辑器不够强大,我用word解释了,这里附截图和部分SQL文:

    这个是从第二个select开始的sql语句:
    SQL> select rownum r,e1.* 2 from (select * from emp order by sal) e1 3 where rownum <=8 4 ; R EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- ---------- --------- ---------- -------------- ---------- ---------- ---------- 1 7369 SMITH CLERK 7902 17-12月-80 800 20 2 7900 JAMES CLERK 7698 03-12月-81 950 30 3 7876 ADAMS CLERK 7788 23-5月 -87 1100 20 4 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 5 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 6 7934 MILLER CLERK 7782 23-1月 -82 1300 10 7 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 8 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 已选择 8 行。

     =======================================逻辑分页=======================================================

    逻辑分页

    •在sql查询时,先从数据库检索出所有数据的结果集
    •在程序内,通过逻辑语句获得分页需要的的数据
    •例如: 检索11-20条 userList.subList(10,20);
     

    * 一次性将数据库中所有记录都查询出来,存放到List集合中,每次查询的时候,List集合subList.截取List集合的长度,完成分页.

    * 优点:只访问一次数据库.

    * 缺点:如果数据量非常大,容易导致内存溢出.

     

    在java中传递封装分页相关信息的时候的JavaBean的设计

    /**
     * 分页查询 数据类 存放分页相关所有数据
     */
    public class PageBean {
        private int pageNum; // 当前页码
        private int numPerPage; // 每页记录条数
        private int totalCount; // 总记录条数
        private int totalPageNum; // 总页数
        private List<Customer> customers; // 当前页需要数据
    }

     

     

  • 相关阅读:
    C#中使用ADOMD.NET查询多维数据集
    Expression表达式树
    SqlBulkCopy 批量复制数据到数据表
    字符串、字符、字节以及bit位小结与疑问
    C#系统委托之Action And Func
    C#中委托演变的的三个阶段
    C# 类成员备忘
    C#函数参数
    MongoDB-Getting Started with the C# Driver
    为MongoDB创建一个Windows服务
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/4025112.html
Copyright © 2011-2022 走看看