你是如何面对大量分页需求的?

    在一个B/S项目中或多或少的都有些需要分页的页面,例如:订单查询,数据统计报表什么的.如果你手下的项目中这样的分页模块特别多,你又如何快速而且非常完美的来完成任务呢?

 

   在园子里面有不少园友写过如何提高编码效率相关文章,都不错,有的就提到了分页控件的开发应用,控件最大的特点就是 功能复用,减少重复代码,从而提高开发人员的效率.有的园友在分页控件开发时把数据源一起给绑定上了,具体怎样实现我并没太多研究,并不是我不认同这种方式,只是我觉的我的方法更加适合我.

 

    同样我也是利用分页控件来开发,我的分页控件只起到分页导航功能,它主要负责 显示分页信息,和具体的数据源没有任何关系,无论是返回DataTable,DataSet,泛型实体集等等。它最大的特点就是分页导航功能和数据源解藕,功能更加灵活。

 

    下面就分享下我个人的做法,不妥之处望指教。


    第一:本文并是把分页控件开发做为重点,有兴趣的朋友可以到我的文章中查找,控件开发(8) (RSS) 这里就先帖图:

 

        图一为最终运行的效果图:

 

    图二:为分页控件的相关属性。此控件分页方式分为url分页(例如:default.aspx?page=1),回发式分页

 

      

      第二:有了分页导航控件,接下来就是取得数据记录了。

        1:数据的最底层:创建查询SQL,这里以一个比较常见的分页存储过程来完成,但又有它与众不同的地方.本人就不详细的说明这个存储过程的用法了,因为所有的说明在里面都有注释。上面的SQL和网上大家看到的通用分页存储过和差不多,主要是利用sql2005的row_number(),它接收页面记录数,索引页,查询条件,排序条件最终返回具体某一页的数据,以及记录总数等

            它与变通分页存储过程最大的不同就是:开发人员对于具体查询部分可以任意写,只是输入参数和返回参数相对固定而已。这点有点类似.net中的模块模式,哈哈,说的远了。


ContractedBlock.gif ExpandedBlockStart.gif Code
--查询学生信息
create proc [dbo].[proc_studentInfo]
@iRowCount 
int--定义一页显示的数据行
@iPageNumber 
int ,--定义当前面的索引
@sCondition varchar(
200),--设置条件
@sCompositor varchar(
50),--设置排序方式
@pageCount 
int out,--返回页面总数
@recordCount 
int out--返回记录总数
@iNextPageNumber 
int out --定义下一页的索引
as
begin
declare @strSql varchar(
8000)
  declare @strDeleteTemTable varchar(
500)
--取得记录总数
                    

declare @strSql2 nvarchar(
4000)  --查询记录语句变量
 
--取得记录总数变量字符串
--取得记录总数
    
set @strSql2='                 
            select @recordCount=count(*) from student 
       
where 1=1 '
     if len(@sCondition)>0
       begin
             
set @strSql2=@strSql2+@sCondition
       end  
   
    print  @strSql2
   execute sp_executesql @strSql2, N
'@recordCount int output',@recordCount output
    
--取得页面总数
    
    
if @recordCount%@iRowCount=0
         begin
           
set @pageCount=@recordCount/@iRowCount
         end
     
if @recordCount%@iRowCount<>0
         begin
           
set @pageCount=@recordCount/@iRowCount+1
         end

set @strSql='
  select * into #tem from (
 select 
*,
row_number() over(order by ID desc) 
as rowNum
 from student
       
where 1=1 '
declare @getDataSet varchar(4000)
set @getDataSet= 
') as tbl2
    select * from #tem
     
where rowNum between '+cast((@iRowCount*@iPageNumber+1) as varchar)+
         ' and '+cast((@iRowCount*(@iPageNumber+1)) as varchar) 
set @strDeleteTemTable=  
' --删除临时表
    drop table #tem'
    if len(@sCondition)>0
       begin
             
set @strSql=@strSql+@sCondition+@getDataSet+@sCompositor+@strDeleteTemTable
       end  
    
else
       begin 
             
set @strSql=@strSql+@getDataSet+@sCompositor+@strDeleteTemTable
       end
    print @strSql
    exec(@strSql) 
   
  
--取得下一页的索引
   
set @iNextPageNumber =@iPageNumber+1 

end
ExpandedBlockStart.gifContractedBlock.gif
/**//*
declare @pageCount int--返回页面总数
declare @recordCount int --返回记录总数
declare @iNextPageNumber int --定义下一页的索引
declare @sCondition varchar(200)--设置条件
declare @sCompositor varchar(50)--设置排序方式
exec proc_studentInfo 10,0,'','',
@pageCount out,@recordCount out ,@iNextPageNumber out
*/


        2:有了查询语句,然后就是在.net环境下封装数据供客户端调用:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
        
/// 根据存储过程名称,搜索条件和表名取得记录集(具有搜索功能)
       
///  by jiangmin 08-09-20
       
///  <param name="iRowCount">每页数据数据量</param>
       
///  <param name="iPageNumber">当前索引页,从0开始</param>
        
/// <param name="procName">存储过程名称</param>
       
/// <param name="sCondition">查询条件,以 and 开始,例如 : and sUserName='张三'</param>
       
/// <param name="strsCompositor">如何排序 例如:order by sUserName</param>
       
/// <param name="pageCount">查询总记录页数</param>
       
/// <param name="recordCount">记录总数</param>
       
/// <param name="iNextPageNumber">下一页的索引数</param>
        
/// </summary>
        
/// <returns></returns>

        public static DataTable getAll_Information(int iRowCount, int iPageNumber, string procName, string sCondition, string strsCompositor, out int pageCount, out int recordCount, out int iNextPageNumber)
ExpandedBlockStart.gifContractedBlock.gif        
{
ContractedSubBlock.gifExpandedSubBlockStart.gif            
数据处理和实现#region  数据处理和实现
            DataTable dt 
= new DataTable();
            DataSet ds 
= new DataSet();
            SqlParameter[] cmdParms 
=
ExpandedSubBlockStart.gifContractedSubBlock.gif               
{
                   
new SqlParameter ("@iRowCount", iRowCount ),
                   
new SqlParameter ("@iPageNumber", iPageNumber ),
                   
new SqlParameter ("@sCondition", sCondition ),
         
new SqlParameter ("@sCompositor", strsCompositor  ),
                   
new SqlParameter ("@pageCount",SqlDbType.Int,4  ),
                   
new SqlParameter ("@recordCount", SqlDbType.Int,4 ),                 
                   
new SqlParameter ("@iNextPageNumber",SqlDbType.Int,4)
               
               }
;
            cmdParms[
4].Direction = ParameterDirection.Output;
            cmdParms[
5].Direction = ParameterDirection.Output;
            cmdParms[
6].Direction = ParameterDirection.Output;


            ds 
= SqlHelper.ExecuteDataSet(CommandType.StoredProcedure, procName , cmdParms);
            pageCount 
= (int)cmdParms[4].Value;
            recordCount 
= (int)cmdParms[5].Value;
            iNextPageNumber 
= (int)cmdParms[6].Value;
            dt 
= ds.Tables[0];
           
            
#endregion


            
return dt;

        }

 

        3:接下来就是客户端绑定数据的操作了,为了说明方便,这里就以一个GridView 来节约时间了。

 

          第一: 页面HTML:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
<asp:GridView ID="GridView1" runat="server">
        
</asp:GridView>
        
<br />
    
        
<cc1:WebCustomControlPager ID="WebCustomControlPager1" runat="server">
<CustomInfoSection CustomInfoTextAlign="NotSet" currentPageText="Page:" sRecordCountText="Total:" ShowCustomInfo="Never"></CustomInfoSection>

<PagerText goFirstText="首 页" PrevPageText="&amp;lt;&amp;lt;上一页" NextPageText="下一页&amp;gt;&amp;gt;" LastPageText="尾 页" sGoText="Go" alreadyaFirstPageText="已经是第一页了" alreadyLastPageText="已经是最后一页了"></PagerText>

<CustomPager IsCustomStyle="False" iRecordCount="1" iRowsCount="10" iPrevCount="5" 
                iNextCount
="5" IsInput="True" UrlPaging="True" UrlPageIndexName="page" 
                IsDisplayFirstText
="True" IsDisplayLastText="True"></CustomPager>
        
</cc1:WebCustomControlPager>

 

          第二:后台代码:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
BLL_getStudentInfo _getStudentInfo = new BLL_getStudentInfo();
            
//当前索引页
            int iPageIndex = 0;

            
if (Request.QueryString["page"!= null && Request.QueryString["page"!= "")
ExpandedBlockStart.gifContractedBlock.gif            
{
                
int.TryParse(Request.QueryString["page"].ToString().Trim().Replace(",",""), out iPageIndex);
                iPageIndex 
= iPageIndex - 1;

            }

            
//页面总数
            int pageCount = 1;
            
//总记录数
            int iRecordCount = 1;
            
//下一页索引
            int iNextPageIndex = 1;
            
//每页10条记录
            int iPageSize = 10;
            DataTable dr 
= _getStudentInfo.BLL_StudentInfo(iPageSize , iPageIndex, "proc_studentInfo"""" order by ID desc"out pageCount, out iRecordCount, out iNextPageIndex);
            
this.GridView1.DataSource = dr;
            
this.GridView1.DataBind();
            
this.WebCustomControlPager1.CustomPager.iRecordCount = iRecordCount;
            
this.WebCustomControlPager1.CustomPager.iRowsCount = iPageSize ;

 

        第三: 最终的效果图:图三:

     从上面的所有过程来看,你要做的工作是什么呢?
 
    第一:把模板分页存储过程中具体查询语句修改下,例如关联其它表操作等等。
    第二:在业务需求页面中引用分页控件及数据绑定控件。
    第三:调用通用查询方法,输入每页记录数,索引页,存储过程名称,查询条件,排序条件查询出记录集。
    第四:设置分页控件相关参数,最重要的是每页记录数和记录总数,其它的可接收默认值。

    这样一个分页操作就基本完成,这就是我对于分页的处理过程,大家在分页时有什么高见不妨分享下。

    优点:

         1:开发员直接编码部分少;

         2:分页样式统一,管理方便;

         3:分页控件与数据库解藕,绑定数据方式灵活.

    缺点:

        1:优点2也就是它的缺点,全站统一分页样式,略显单调,不过可自定义控件样式.

        2:如果没有update pannel的支持,要想实现无刷新分页有一定的困难.

   

  

转载于:https://www.cnblogs.com/ASPNET2008/archive/2008/09/22/1295609.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值