aspnetpager+repeater+oracle实现分页功能

简介: 一、设计原理阐述数据查询分页,这个功能相信大家都很熟悉,通过数据库或其它数据源进行查询操作后,将获得的数据显示到界面上,但是由于数据量太大,不能一次性完全的显示出来,就有了数据分页的需求。

一、设计原理阐述

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

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;
目录
相关文章
|
缓存 运维 Java
nacos常见问题之点击下线提示报错如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
557 2
|
Dubbo Cloud Native 网络协议
【Dubbo3技术专题】「服务架构体系」第一章之Dubbo3新特性要点之RPC协议分析介绍
【Dubbo3技术专题】「服务架构体系」第一章之Dubbo3新特性要点之RPC协议分析介绍
370 1
|
算法 程序员 应用服务中间件
推荐一款基于docker部署的个人免费笔记工具wiznote
推荐一款基于docker部署的个人免费笔记工具wiznote
推荐一款基于docker部署的个人免费笔记工具wiznote
|
11月前
|
机器学习/深度学习 人工智能 算法
《量子比特大阅兵:不同类型量子比特在人工智能领域的优劣势剖析》
量子比特与人工智能的融合正开启全新科技大门。超导量子比特集成度高,适合大规模神经网络训练,但需极低温环境;离子阱量子比特精度高、稳定性好,适于金融等领域,但扩展性差;光量子比特速度快、带宽高,利于量子通信,但易受干扰。各类型量子比特各有优劣,未来将推动AI技术发展,带来更多创新突破。
247 7
|
API Apache 对象存储
数据编排的现代时代:从数据碎片化到协作
数据工程与软件工程长期存在分歧,各自拥有独特的工具和最佳实践。本文探讨了数据编排器的角色及其最新趋势,如何使这两个领域更加紧密地结合。数据编排通过协调数据的提取、转换和服务,解决了多数据源、目标和工具的复杂性。文中介绍了 ELT 流程、不同类型的编排工具(如 Apache Airflow 和 Apache Flink),以及未来可组合数据系统的开放标准,如 Apache Parquet 和 Apache Arrow。这些标准有助于简化数据共享和治理,推动数据系统的未来发展。
444 2
数据编排的现代时代:从数据碎片化到协作
|
人工智能 机器人 UED
数字人模型网页手机云推流语音交互
随着AI技术的发展,数字人与大型语言模型的结合迎来了新机遇,各类数字人服务不断涌现,应用于多种场景。点量小芹发现许多厂商仍在探索如何优化数字人在移动端的表现。通过云推流实时渲染解决方案。无论是直播中的数字人形象定制,还是网页客服与大屏讲解的应用,只需将数字人模型置于服务器端,借助云渲染技术,用户即可在网页或移动设备上轻松使用高精度的数字人,显著降低硬件需求,提升互动体验。
470 14
|
存储 人工智能 机器人
基于AI人工智能大模型下的物流运输业务场景搭建
党的二十大报告深刻阐述了我国物流运输发展事业上所获得的整体成绩,并对今后一段时期内对大数据背景下物流运输新事业,新管理,新运营进行了深度分析,研究。提出运用先进技术,智能化设备及高端产品等新型手段提高企业的高质量发展构想。为努力打造新型智慧物流,开启智能化物流打开了新的局面。 引言 随着科技的不断发展,设备的不断更新,智能化技术的不断涌现,低代码技术,人工智能AI技术等新型智能化应用逐步成为行业应用的主流模式,大数据背景下,阿里云,冀之云,宝之云等“云”技术服务平台成为了行业自动化办公应用中不可或缺的一部分,本文以人工智能AI技术在物流业行业发展中的设计与应用为例,作简要说明。
|
图形学
【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统(下)
【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统
541 1
|
监控 前端开发 JavaScript
使用JavaScript实现实时报警功能的办公电脑上网监控软件:前端代码
在今天的数字化时代,监控软件已成为许多组织和企业必不可少的一部分,用于保护数据和确保系统的正常运行。本文将介绍如何使用JavaScript编写前端监控软件,包括实时报警功能的实现。我们将探讨一些关键的代码示例,以展示如何构建这样的系统。最后,我们还会讨论如何自动将监控到的数据提交到一个网站。
470 4
|
网络协议 Ubuntu Shell