一、设计原理阐述

数据查询分页,这个功能相信大家都很熟悉,通过数据库或其它数据源进行查询操作后,将获得的数据显示到界面上,但是由于数据量太大,不能一次性完全的显示出来,就有了数据分页的需求。这个需求在实际开发过程中还是普遍存在的,也给出了不同的实现,正常的的几种思路有:

1、一次性将所有要查询的数据查询出来,然后在客户端处理,分页显示相应的数据。

2、每次只取我所需要的那部分数据,在服务器端分页完成后,再发送到客户端显示。

在asp.net中,GridView控件自带的分页功能,就是引用了第一种思路,但是这个方法有很大的弊端,每次请求都是将所有的数据,一次性的读入到DataTable或DataSet或其它集合当中,然后再分区间显示出来,显然造成网络资源的紧张。而如果在服务器端将数据已经分好页,再传送,网络资源显然压力大幅度减少,这样子就提高了查询的效率。

如果在思路2的基础上,再进行优化,还可以有以下几种思路:

1)通过SQL语句分页

2)引用动态SQL语句进行分页

3)引用存储过程进行数据分页

显然这里推荐第3种解决方案,理由是:存储过程由于在服务器端数据库已经预先编译好,不需要运行时编译,应该可以直接运行,本身的运行效率比SQL要高;安全性高,防止SQL注入式攻击(带参数的SQL语句比简单的SQL拼接要安全);便于代码管理和复用,完全可以直接将存储过程代码保存起来,在下一个项目中直接引用。

至此,数据查询分页原理已经设计完毕,再进一步,可以引用web页面静态化技术(不是伪静态,就是真的生成html文件),定期的将动态html生成静态html,这样可以有效提高页面的访问速度,显然已经不需要每次再到数据库中查询了,省去了数据库查询和网络数据传送的时间。

二、代码实例

不论是asp、asp.net、jsp、php还是其它web开发语言,涉及到分页这一块,原理都是想通的,这里仅以asp.net为例,完整的设计一个数据查询分页功能。

1、完全自己写分页代码

这个无非就是利用sql语句的分页功能实现分页,C#后台拼接各种字符串,这里不想过多阐述。

2、引用第三方分页控件,比如aspnetpager等

首先新建一个分页实体类:

public class MPage
{
private string pagesql;//产生的sql语句
private int pagesize;//每页显示的条数
private int pageindex;//显示页的索引 /// <summary>
/// 产生分页的sql语句 sql要求必须包含rownum字段且其别名为rn,如例子:select rownum rn,t.* from test t
/// </summary>
public string Pagesql
{
get { return pagesql; }
set { pagesql = value; }
} /// <summary>
/// 每页显示的条数
/// </summary>
public int Pagesize
{
get { return pagesize; }
set { pagesize = value; }
} /// <summary>
/// 显示页的索引 从0开始
/// </summary>
public int Pageindex
{
get { return pageindex; }
set { pageindex = value; }
}
}

分页查询类:

/// <summary>
/// 获取分页的记录
/// </summary>
/// <param name="page">封装的页面对象</param>
/// <param name="result">反馈的结果</param>
/// <returns>结果集的表</returns>
public DataTable GetPageRecord(MPage page, out ArrayList result)
{
OracleParameter[] oracleParameter = new OracleParameter[6]; oracleParameter[0] = new OracleParameter("p_pagesql", OracleType.VarChar);
oracleParameter[0].Direction = ParameterDirection.Input;
oracleParameter[0].Value = page.Pagesql; oracleParameter[1] = new OracleParameter("p_pagesize", OracleType.Number);
oracleParameter[1].Direction = ParameterDirection.Input;
oracleParameter[1].Value = page.Pagesize; oracleParameter[2] = new OracleParameter("p_pageindex", OracleType.Number);
oracleParameter[2].Direction = ParameterDirection.Input;
oracleParameter[2].Value = page.Pageindex; oracleParameter[3] = new OracleParameter("p_totalcount", OracleType.Number);
oracleParameter[3].Direction = ParameterDirection.Output; oracleParameter[4] = new OracleParameter("p_pagecount", OracleType.Number);
oracleParameter[4].Direction = ParameterDirection.Output; oracleParameter[5] = new OracleParameter("p_currentpagedata", OracleType.Cursor);
oracleParameter[5].Direction = ParameterDirection.Output; DataAccess da = new DataAccess();
return da.ExecuteProcedureWithTable(DBConn.sb, ref oracleParameter, "p_app_page", out result);
}

用aspnetpager控件和repeater控件结合oracle存储过程绑定:

/// <summary>
/// 用aspnetpager控件和repeater控件结合oracle存储过程绑定
/// </summary>
/// <param name="aspnetpager">aspnetpager控件</param>
/// <param name="bindingtarget">repeater控件</param>
/// <param name="pagesql">执行的sql语句</param>
public void BindingRepeaterWithAspNetPager(AspNetPager aspnetpager, Repeater bindingtarget, string pagesql)
{
int recordcount = 0;
ArrayList result = null;
MPage page = new MPage();
page.Pagesize = aspnetpager.PageSize;//每页显示的条数
page.Pageindex = aspnetpager.StartRecordIndex / aspnetpager.PageSize;//显示页的索引 从0开始
page.Pagesql = pagesql;//产生分页的sql语句 sql要求必须包含rownum字段且其别名为rn,如例子:select rownum rn,t.* from test t bindingtarget.DataSource = GetPageRecord(page, out result);
bindingtarget.DataBind(); if (result != null && result.Count > 0)
{
if (int.TryParse(result[3].ToString(), out recordcount))
{
aspnetpager.RecordCount = recordcount;
}
else
{
aspnetpager.RecordCount = 0;
}
}
}

aspnetpager控件和repeater控件直接绑定datatable:

/// <summary>
/// aspnetpager控件和repeater控件直接绑定Datatable
/// </summary>
/// <param name="aspnetpager">aspnetpager控件</param>
/// <param name="bindingtarget">repeater控件</param>
/// <param name="dt">Datatable</param>
public void BindingRepeaterWithAspNetPagerByDataTable(AspNetPager aspnetpager, Repeater bindingtarget, DataTable dt)
{
PagedDataSource pds = new PagedDataSource();
pds.AllowPaging = true;
pds.PageSize = aspnetpager.PageSize;
pds.CurrentPageIndex = aspnetpager.CurrentPageIndex - 1;
pds.DataSource = dt.DefaultView;
aspnetpager.RecordCount = pds.DataSourceCount; bindingtarget.DataSource = pds;
bindingtarget.DataBind();
}

前台代码:

<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table cellpadding="0" cellspacing="0" border="1" width="100%">
<thead align="center">
<tr>
<td style="width: 5%;">
<label>
<b>序号</b></label>
</td>
<td style="width: 10%;">
<label>
<b>单位代码</b></label>
</td>
<td style="width: 25%;">
<label>
<b>单位名称</b></label>
</td>
<td style="width: 8%;">
<label>
<b>单位申报所属期</b></label>
</td>
<td style="width: 8%;">
<label>
<b>单位申报基数</b></label>
</td>
<td style="width: 8%;">
<label>
<b>单位申报个人基数</b></label>
</td>
<td style="width: 8%;">
<label>
<b>单位应缴总金额</b></label>
</td>
<td style="width: 8%;">
<label>
<b>单位到帐总金额</b></label>
</td>
<td style="width: 8%;">
<label>
<b>单位到帐时间</b></label>
</td>
</tr>
</thead>
</HeaderTemplate>
<ItemTemplate>
<tr align="center" style='background-color: <%#(Container.ItemIndex%2==0)?"#eeeeee":"#ffffff"%>'
onmouseover="this.style.background='#ddeeff'" onmouseout="this.style.background='<%#(Container.ItemIndex%2==0)?"#eeeeee":"#ffffff"%>'">
<td>
<label>
<%#Eval("rn") %></label><!--序号-->
</td>
<td>
<label>
<%#Eval("dwdm") %></label><!--单位代码-->
</td>
<td>
<label>
<%#Eval("dwmc") %></label><!--单位名称-->
</td>
<td>
<label>
<%#Eval("dwsbssq") %></label><!--单位申报所属期-->
</td>
<td>
<label>
<%#Eval("dwsbjs") %></label><!--单位申报基数-->
</td>
<td>
<label>
<%#Eval("dwsbgrjs") %></label><!--单位申报个人基数-->
</td>
<td>
<label>
<%#Eval("dwyjzje") %></label><!--单位应缴总金额-->
</td>
<td>
<label>
<%#Eval("dwdzzje") %></label><!--单位到帐总金额-->
</td>
<td>
<label>
<%#Eval("dwdzsj") %><!--单位到帐时间 --></label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<webdiyer:AspNetPager ID="AspNetPager1" runat="server" AlwaysShow="True" Font-Size="10pt"
Font-Names="gb2312" CustomInfoHTML="第%CurrentPageIndex%页 共%RecordCount%条记录" ShowCustomInfoSection="Right"
SubmitButtonText="跳转" TextAfterPageIndexBox="页" OnPageChanged="AspNetPager1_PageChanged"
CurrentPageButtonPosition="Center" CustomInfoSectionWidth="45%" CustomInfoTextAlign="Center"
PageSize="25" ShowPageIndex="True" Width="92%">
</webdiyer:AspNetPager>

oracle脚本:

create or replace package jssb.pck_page is  

type T_Page is ref cursor; --定义游标变量用于返回记录集  

procedure getpagerecord(
pindex in number, --分页索引
psql in varchar2, --产生dataset的sql语句
psize in number, --页面大小
pcount out number, --返回分页总数
v_cur out T_Page --返回当前页数据记录
); end pck_page;
create or replace procedure jssb.p_app_GetCount(
p_sql in varchar2,
p_count out number
)
as v_sql varchar2(1000);
v_prcount number; begin v_sql := 'select count(*) from (' || p_sql || ')';
execute immediate v_sql into v_prcount;
p_count := v_prcount; --返回记录总数 end p_app_GetCount;
create or replace procedure jssb.p_app_page(
p_pagesql in varchar2,--产生分页的sql语句 sql要求必须包含rownum字段且其别名为rn,如例子:select rownum rn,t.* from test t
p_pagesize in number, --每页显示的条数
p_pageindex in number,--显示页的索引 从0开始
p_totalcount out number,--总条数
p_pagecount out number,--总页数
p_currentpagedata out pck_page.T_Page --返回当前页的数据
)
as
begin
pck_page.getpagerecord(p_pageindex,p_pagesql,p_pagesize,p_pagecount,p_currentpagedata);
p_app_getcount(p_pagesql,p_totalcount);
end;
create or replace package body jssb.pck_page is
procedure getpagerecord(
pindex in number,
psql in varchar2,
psize in number,
pcount out number,
v_cur out T_Page
)
as v_sql varchar2(1000);
v_count number;
v_plow number;
v_phei number;
begin v_sql := 'select count(*) from (' || psql || ')';
execute immediate v_sql into v_count;
pcount := ceil(v_count/psize); v_phei := pindex * psize + psize;
v_plow := v_phei - psize + 1;
--psql := select rownum rn,t.* from test t ; --要求必须包含rownum字段
v_sql := 'select * from (' || psql || ') where rn between ' || v_plow || ' and ' || v_phei ; open v_cur for v_sql; end getpagerecord; end pck_page;

aspnetpager+repeater+oracle实现分页功能的更多相关文章

  1. JSP+Oracle实现分页功能

    Oracle: create table load( id char(200) not null, title varchar2(100) not null, time varchar2(100) n ...

  2. oracle实现分页功能 limit功能例子

    oracle数据库不支持mysql中limit功能,但可以通过rownum来限制返回的结果集的行数,rownum并不是用户添加的字段,而是oracle系统自动添加的. 记录两种常用方法: (1)使查询 ...

  3. Repeater控件使用(含删除,分页功能)

    Repeater控件使用(含删除,分页功能) 摘自:http://www.cnblogs.com/alanliu/archive/2008/02/25/914779.html 前臺代碼 <%@ ...

  4. java ssm框架实现分页功能 (oracle)

    java web 实现分页功能 使用框架:ssm 数据库:oracle 话说 oracle 的分页查询比 mysql 复杂多了,在这里简单谈一下: 查询 前十条数据: SELECT * FROM( S ...

  5. ASP.NET--Repeater控件分页功能实现

    这两天由于‘销售渠道’系统需要实现新功能,开发了三个页面,三个界面功能大致相同. 功能:分页显示特定sql查询结果,点击上一页下一页均可显示.单击某记录可以选定修改某特定字段<DropDownL ...

  6. mysql、sql server、oracle数据库分页查询及分析(操作手册)

    1.mysql分页查询 方式1: select * from table order by id limit m, n; 该语句的意思为,查询m+n条记录,去掉前m条,返回后n条记录.无疑该查询能够实 ...

  7. 使用AspNetPager与GridView完成分页

    使用AspNetPager与GridView完成分页   由于GridView的分页功能实在是太弱了,所以需要使用强大的AspNetPager来作为分页控件.最简单的办法就是GridView控件下面接 ...

  8. Repeater 无刷新分页

    原文:http://blog.csdn.net/Sandy945/archive/2009/05/22/4208998.aspx 本文讲述的是如何利用 XMLHttpRequest 来对 Repeat ...

  9. Mybatis Generator实现分页功能

    Mybatis Generator实现分页功能 分类: IBATIS2013-07-17 17:03 882人阅读 评论(1) 收藏 举报 mybatisibatisgeneratorpage分页 众 ...

随机推荐

  1. Codeforces Round #322 (Div. 2) A. Vasya the Hipster 水题

    A. Vasya the Hipster Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/581/p ...

  2. iOS开发——基本常识篇&各种控件默认高度

    各种控件默认高度   1.状态栏 状态栏一般高度为20像素,在打手机或者显示消息时会放大到40像素高,注意,两倍高度的状态栏在好像只能在纵向的模式下使用.如下图 用户可以隐藏状态栏,也可以将状态栏设置 ...

  3. Unity手游之路&lt;七&gt;角色控制器

    我们要控制角色的移动,能够所有细节都由自己来实现.控制角色模型的移动,同一时候移动摄影机,改变视角.当然Unity也提供了一些组件,能够让我们做更少的工作,实现我们所期望的功能.今天我们就一起系统来学 ...

  4. python的内存管理机制 图解+Django Web开发学习笔记

    http://www.cnblogs.com/CBDoctor/p/3781078.html http://www.cnblogs.com/vamei/p/3232088.html http://bl ...

  5. 文件I/O之fcntl函数

    fcntl函数可以改变已打开的文件的性质. #include <fcntl.h> int fcntl( int filedes, int cmd, ... /* int arg */ ); ...

  6. git svn 5点区别

    如果你在读这篇文章,说明你跟大多数开发者一样对GIT感兴趣,如果你还没有机会来试一试GIT,我想现在你就要了解它了. GIT不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等.如果 ...

  7. 在 iOS 8 中使用模糊效果

    在 iOS 7 出來一個背景模糊的效果, Apple 官方的 sample code 則有提供怎麼使用 vImage, Quartz 來實作這個效果.接著在 iOS 8 出來之後,則提供了  UIVi ...

  8. 16% off MPPS V16 ECU tuning tool for EDC15 EDC16 EDC17

    EOBD2.FR is offering 16% discount off the latest MPPS V16 ECU chip tuning tool. The device is now so ...

  9. (转)fastdfs group通过添加硬盘扩容

    通过给group的机器添加硬盘的方式,实现某个group的扩容. fastdfs在一台服务器支持多个store_path,每个store_path指向一个存储路径.url “M00/3F/E1/oYY ...

  10. MATLAB-ginput函数问题

    functions:Graphical input from mouse or cursor ginput提供了一个十字光标使我们能更精确的选择我们所需要的位置,并返回坐标值.函数调用形式为: [x, ...