zoukankan      html  css  js  c++  java
  • 主流数据库分页查询介绍

    1 背景概述

         由于在项目中需要在页面上显示数量非常多的数据, 在进行数据库查询时首先会把所有的数据都查询出来,然后在进行显示,这时候分页查询的操作就必不可少了,本文介绍Mysql、Oracle、sql Server 三种数据库进行分页查询的用法。

    2 预期读者

    1. 数通畅联内部员工

    2. 广大计算机爱好者

    3 名词解释

    • 分页查询

        就是将将过多的结果在有限的界面上分多页来显示,一般将分页查询分为两类:逻辑分页、物理分页。
        逻辑分页是在用户第一次访问时,将数据库的所有记录全部查询出来,添加到一个大集合中,然后存放在session对象,再通过页码计算出当前页需要显示的数据内容,存储到一个小的list的集合中,并将其存储到request对象中,跳转到JSP页面,进行遍历显示。 当用户第二次访问时,只要不关闭浏览器,还会从session中获取数据,来进行显示。因为此种方法是在内存的session对象中进行计算分页显示的,而不是真正的将我们数据库进行分页的,所以叫做逻辑分页。
        缺点:如果需要查询的数据量过大,session将耗费大量的内存;因为是在session中获取数据,如果第二次或者更多此的不关闭浏览器访问,会直接访问session,从而不能保证数据是最新的。
        优点:统一代码处理方式,较容易跨数据库做迁移。
        物理分页,使用数据库自身所带的分页机制,例如,Oracle数据库的rownum,或者Mysql数据库中的limit等机制来完成分页操作。因为是对数据库的数据进行分页条件查询,所以叫物理分页。每一次物理分页都会去连接数据库。
    优点:数据能够保证最新,由于根据分页条件会查询出少量的数据,所以不会占用太多的内存。

    • CTE(Common Table Expression,公用表表达式)

        该表达式源自简单查询,可以认为是在单个 SELECT、INSERT、UPDATE、DELETE 或 CREATE VIEW 语句的执行范围内定义的临时结果集。CTE 与派生表类似,具体表现在不存储为对象,并且只在查询期间有效。与派生表的不同之处在于,CTE 可自引用,还可在同一查询中引用多次。

    4 实现思路

        通过物理分页的方法进行数据库查询。

    5 实现步骤

        首先通过开发平台新建一个工程,使用新工程中的系统日志模块作为样例,进行mysql和oracle的分页查询功能

    5.1 Mysql

    • 在数据库中进行操作:

        mysql的分页查询是最简单的,借助关键字limit即可实现查询,查询语句通用形式:


    select o.* from (sql) o limit firstIndex,pageSize

        其中的sql可以是单表查询的结果也可以是多表查询的结果
        firstIndex为显示结果的起始位置(mysql是从0作为起始位置的)
        pageSize为显示记录数
        直接对表进行查询如下,我们可以看到查询时间是0.005s

    wKiom1ZWxEzyLKXTAAFgdhCyTRA028.png
        采用分页查询,一页显示15条数据,查询时间是0.001s

    wKiom1ZWxGfi1Z6XAAEhlBl71_o675.png

    • 在工程中体现:

        首先在工程中找到SystemLogQueryImpl.java这个类

    wKioL1ZWxNvDmBY7AAExoJghKhM210.png
        其中有一点需要注意,方法的返回值需要是PageList而不是List

    wKioL1ZWxOuyt7ofAABEQ7x8kFU895.png
        在开发平台中这个类是日志功能的服务实现类,

    wKiom1ZWxKDyDyjzAADV6sAMsEI607.png
        其中,ec_p为页数,ec_rd为显示记录数
        staratNum为起始索引,endNum为结束索引
        由于MySQL的起始索引是从0开始的,需要对得到的起始索引减一,显示记录数的计算方法为: 结束索引-起始索引+1
        在sqlMap中的体现如图:

    wKioL1ZWxTyxmGmsAABu1e4h08g720.png
        在页面上的显示:

    wKiom1ZWxL3jxZN1AAJsyRTenA4851.png
        可以在页面选择显示的页码和记录数

    wKioL1ZWxV_yyYUqAAITrx3PwK4963.png

    5.2 Oracle

        Oracle的查询方法有两种:ROWNUM、row_number()

    5.2.1 ROWNUM

    • 在数据库中进行操作:

        查询语句通用形式:

    select * from(select o.*,ROWNUM num from(sql) o where ROWNUM<=(endIndex)) where num>=firstIndex

        直接对表进行查询,耗时16msecs

    wKiom1ZWxRrgAFFFAAGBuwyMzgg868.png
        采用分页算法进行查询是,耗时7msecs

    wKiom1ZWxTuCsMErAAFzkHwvvDE101.png

    • 在工程中体现:

        找到对应的服务实现类:

    wKioL1ZWxbDQ9xqGAADfO5TPyhA052.png
        服务实现类的内容:

    wKioL1ZWxcKiwi8qAADWA1mhjNE951.png
        startNum为起始索引,endNum为结束索引
        因为ROWNUM方法中使用的两个参数一个是起始索引,一个是结束索引,所以可以直接使用。
        在sql中的体现:

    wKiom1ZWxZCR8D2fAACAZuXDq5E822.png
        在页面上的效果:

    wKiom1ZWxaLTxlNXAAJTaKV23Es068.png

    5.2.2 row_number()

        查询语句通用形式:

    select * from(select * from(select t.*,row_number() over(order by orderColumn) as rownumber from(sql) t) p where p.rownumber>firstIndex) where rownum<=pageSize

        直接对表进行查询,耗时22msecs

    wKioL1ZWxhiyv9DbAAGOT9Hy9VU701.png
        使用分页查询语句进行查询,耗时12msece

    wKioL1ZWxifCf9ARAAF8AFn5kak829.png

    • 在工程中体现:

        服务实现类的内容和ROWNUM一样,区别在sql中

    wKiom1ZWxdiy5qlEAACCfjKR4aI046.png
        由于在sql中添加了order by排序函数,查询速率会变慢,所以在开发平台中不采用这种方法。
        对于oracle的分页查询,他们的主要区别是:使用rownum进行排序的时候是先对结果集加入伪列rownum然后再进行排序,而函数row_number()在包含排序从句后是先排序再计算行号码。

    5.3 Sqlserver

        由于sqlserver版本比较多,分页查询的方式也有不同之处

    5.3.1 Sqlserver 2005/2008中使用row_number()

        查询通用形式:

    SELECT * FROM (SELECT *,ROW_NUMBER() OVER (ORDER BY orderColumn) AS RowNumber FROM tableName) EmployeePage WHERE RowNumber > =startIndex AND RowNumber <= endIndex ORDER BY orderColumn
    GO

        直接查询表,如图
     
    wKiom1ZWxemDqCrvAADyKIPc_dg843.png
        使用分页查询,如图

    wKioL1ZWxleTcvrtAAFHeeg7BBk002.png

    5.3.2 SQL 2005/2008用CTE的方式实现

         查询通用形式:

    WITH EmployeePage AS (SELECT *,ROW_NUMBER() OVER (ORDER BY orderColumn) AS RowNumber FROM tableName)
    SELECT *FROM EmployeePage WHERE RowNumber > =firstIndex AND RowNumber <= endIndex ORDER BY orderColumn
    GO

         使用分页查询,如图:

    wKiom1ZWxgugzuvTAAF-BfdWcHw429.png

    5.3.3 SQL SERVER 2012支持了OFFSET

        查询通用形式,如下:

    SELECT * FROM tableName
    ORDER BY orderColumn
    OFFSET (page-1) ROWS FETCH NEXT size ROWS ONLY

        Page指需要显示的页数
        Size指需要显示的记录数
         由于本人现在没有sqlserver 2012的数据库,暂时无法做性能的测试

    6 附件及说明

        附件中有两个样例工程pagingquery4mysql和pagingquery4oracle,使用最新版的aeai dp开发平台导入后查看使用。

    主流数据库分页查询介绍文档及附件       下载

  • 相关阅读:
    成绩
    多态与异常处理
    大道至简终结版
    继承与接口
    大道至简之编程到工程
    数组元素相加
    数组元素必须具有相同的数据类型?
    大道至简之失败的过程也是过程
    作业
    感想之流于形式的沟通
  • 原文地址:https://www.cnblogs.com/agileai/p/4998262.html
Copyright © 2011-2022 走看看