一、设计原理阐述

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

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. android常见错误-The container 'Android Dependencies' references non existing library

    The container 'Android Dependencies' references non existing library

  2. Zmodem transfer canceled by remote side

    linux sz命令时报这个错误,看了一头雾水. 仔细看了一下发现竟然是要sz的文件名称写错了,抱着个错误和误导人呢.估计路径写错了也是这个错误.

  3. js 如何将无限级分类展示出来

    这个需要运用递归. 案例:将数据以 ul li ul li形式展现在div中. <div id="div"></div> 数据格式为json: var da ...

  4. java.util.Scanner的日常用法

    Scanner是新增的一个简易文本扫描器,在 JDK 5.0之前,是没有的.查看最新在线文档: public final class Scanner extends Object implements ...

  5. mysql datetime、date、time、timestamp区别

    我们看看这几个数据库中(mysql.oracle和sqlserver)如何表示时间 mysql数据库:它们分别是 date.datetime.time.timestamp和year.date :“yy ...

  6. iOS 开发中使用 NSURLProtocol 拦截 HTTP 请求

    这篇文章会提供一种在 Cocoa 层拦截所有 HTTP 请求的方法,其实标题已经说明了拦截 HTTP 请求需要的了解的就是 NSURLProtocol. 由于文章的内容较长,会分成两部分,这篇文章介绍 ...

  7. Android_AsyncTask_json

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...

  8. Android_ViewPager

    view1源代码及xml资源文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout ...

  9. Java 开源分布式缓存框架Ehcache

    http://www.codeceo.com/article/java-ehcache.html

  10. [转]Install App to SD

    本文转自:http://www.douban.com/group/topic/29597344/ If you want to move more apps to the SD card, you'l ...