我自己写的一个分页控件(源码和演示代码)PostBack分页版 for vs2003、SQL Server

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介: 温馨提示:asp.net分页控件已经升级了,基于.net2.0 ,支持多种数据库。正式命名为:QuickPager Asp.net 2.0 分页控件。 网站:www.natureFW.com 下载:http://www.naturefw.com/down/List1.aspx 在线演示:http://demo.naturefw.com 上一篇随笔:我的分页控件(未完,待续)——控件件介绍及思路 一、分页控件的工作层次    如果按照三层的划分方式来说,应该算作工作在 UI层 和 逻辑层。


温馨提示:
asp.net分页控件已经升级了,基于.net2.0 ,支持多种数据库。
正式命名为:QuickPager Asp.net 2.0 分页控件。

网站:www.natureFW.com

下载:http://www.naturefw.com/down/List1.aspx

在线演示:http://demo.naturefw.com


上一篇随笔:
我的分页控件(未完,待续)——控件件介绍及思路

一、分页控件的工作层次
    如果按照三层的划分方式来说,应该算作工作在 UI层 和 逻辑层。
    在分页控件内部会调用“数据访问函数库”来访问数据库,得到记录集之后再绑定到指定的显示数据的控件。
 
    当然这里只是打个比方,我并没有按照三层的规范来写这个分页控件,我的目的只是想少写点代码。

二、适用范围
    目前适用于 vs2003 和 SQL Server 2000 
    因为是在这两个环境下开发的,尤其是对于  SQL Server 2000 进行了一些优化。
    当然也是可以在 vs2005 和 SQL Server 2005 下使用,只是没有针对 05系列 进行优化。
    可以在vs2005的项目里引用 分页控件的dll文件,但是可能需要在电脑上安装 .net1.1 的框架。

三、优点
    1、不必使用存储过程就可以达到高效率的分页效果。

    2、使用两种(或者多种)分页算法,来达到效率和通用的完美统一。当然也可以使用不同的算法应对不同的数据库。

    3、按需所取。如果一页显示20条记录,那么分页控件只会从数据库里提取20条数据。

    4、支持查询条件,您可以很方便的添加查询条件,实现复杂的检索功能。

    5、利用ViewState 来保存一些信息,节省服务器的资源。
        比如在第一次显示数据的时候会统计总记录数,然后把总记录数保存到ViewState里面,当点击下一页的时候不用重新统计。
        还有其他的信息也会保存到 ViewState  里面。

    6、在百万级数据下也有很好的表现,下面有测试数据,不信的话,可以下载demo亲自测试。
    
    7、使用方便,只需要设置几个属性就可以,不必处理分页时产生的事件。

    8、支持多种显示数据的控件,比如DataGrid、DataList、Reapeter、DropDownList等。只要是能够使用DataTable绑定的控件都支持。

    9、可以使用键盘快速翻页。
        “左方向”键:向前翻页;
        “右方向”键:向后翻页;
        PageUp键:上一页;
        PageDown键:下一页;
        Home:首页;
        End:末页;
        数字键:1到10页,0表示第十页


四、缺点
    1、多表联合查询的时候需要使用视图。就是要先建立一个视图。
    2、第一种分页算法不要求数据表一定要有主键,但是第二种分页算法要求表必须有主键,而且不能使联合主键。
    3、不能很灵活的应对多种数据库。
    4、内部代码比较混乱,05年底写的,一直想整理,但是都没有开始整理,只是做了小的升级和修改bug。

五、使用方法
    先在 Page_Load 设置显示数据的控件 比如 DataGrid,
    

private   void  Page_Load( object  sender, System.EventArgs e)
        
{
            
//设置显示数据的控件,注意,不是ID而是实例
            myPage.PubShowDataObject = this.DG ;        
            
if (!Page.IsPostBack)
            
{
                SetPage();
            }

        }

    然后根据情况设置分页控件的其它属性
    第一种分页算法的属性设置。单字段排序,且排序字段没有重复记录
    
private   void  SetPage()
        
{
            
//简单的分页方式
            
//只能有一个排序字段,且排序字段的值没有重复的。

            myPage.SqlTableNames 
= "Products";        //要显示数据的表名或者视图名
            myPage.SqlColumns  = "*";                //要显示字段
            myPage.SqlOrderColumn  = "ProductID";    //排序字段
            myPage.SqlOrderColumnKind = "int";        //排序字段的类型。可选项:"int"、"string"、"datetime"、"float"
            myPage.SqlPageSize  = 5;                //一页显示的记录数
            myPage.IsOrderDesc = true;                //倒序显示记录
            
            
//查询条件
            myPage.SqlQuery = "";                            
            
            
//查询条件,回发后再次执行 myPage.CreateQuery() 的时候,会把 SetQuery 添加到 SqlQuery 里。
            myPage.SetQuery = "";                            
            
            myPage.CreateQuery();        
//生成查询语句        回发后生成的查询语句可以保存。
            myPage.BindFirstPage();        //显示第一页的数据

        }

    第二种分页算法的属性设置。多排序字段,或者是单排序字段且排序字段有重复记录(其实是转换成了多排序字段的情况)。
    
private   void  SetPage2()
        
{
            
//多排序字段的分页方式
            
//支持多字段排序。

            myPage.SetSQLKind 
= "2";                //设置分页算法
            myPage.SqlTableNames = "Products";        //要显示数据的表名或者视图名
            myPage.SqlColumns  = "*";                //要显示字段
            myPage.SqlPowerIDColumn = "ProductID";    //主键字段名称

            
//一个排序字段,且有重复值的情况,不能把主键字段放在下面的两个属性里面
            myPage.SqlPowerOrderColumnA = "UnitPrice ,ReorderLevel desc";            //排序字段 按开始日期正序
            myPage.SqlPowerOrderColumnB = "UnitPrice desc,ReorderLevel ";            //这里要设置为上面的字段的相反的排序方式。
            
            
//多个排序字段的情况
            myPage.SqlPowerOrderColumnA = "UnitPrice";                //排序字段 按开始日期正序
            myPage.SqlPowerOrderColumnB = "UnitPrice desc";            //这里要设置为上面的字段的相反的排序方式。

            myPage.SqlPowerHasMoreValue 
= true;                        //最后一个排序字段是否有重复值
            myPage.SqlPageSize  = 5;                                //一页显示的记录数

            myPage.SqlQuery 
= "";                            //查询条件,回发后该属性失效
            myPage.SetQuery = "";                            //查询条件,回发后该属性可以保存
            
            myPage.CreateQuery();        
//生成查询语句        回发后生成的查询语句可以保存。
            myPage.BindFirstPage();        //显示第一页的数据

        }


    查询情况,点击查询按钮后需要做的事情。这里只是作了一个演示,可以增加更多的查询条件
    
实现查询功能 #region 实现查询功能
        
private void Btn_Search_Click(object sender, System.EventArgs e)
        
{
            
//Response.Write(myPage.SqlQuery);    输出查询条件

            
//查询数据
            string query = "";        //保存查询条件 where 后面的sql语句
            string tmp = "";        //保存查询关键字

            
//第一个查询条件
            tmp = this.Txt_ProductName.TextTrimNone ;
            
if (tmp.Length > 0)
                query 
= "ProductName like '%" + tmp + "%'";

            
//其他的查询条件
            tmp = Txt_UnitPrice1.TextTrimNone ;
            
string tmp2 = Txt_UnitPrice2.TextTrimNone ;
            
            
if (tmp.Length > 0)
            
{
                
判断是否是数字#region 判断是否是数字
                
if (!Functions.IsInt(tmp))
                
{
                    Functions.PageRegisterAlert(Page,(
"请输入数字"));
                    
return;
                }

                
                
if (!Functions.IsInt(tmp2))
                
{
                    tmp2 
= tmp;
                }

                
                
#endregion


                
if (query.Length ==0)
                    query 
= "UnitPrice between " + tmp + " and " + tmp2;
                
else
                    query 
+= " and UnitPrice between " + tmp + " and " + tmp2;
            }


            myPage.SqlQuery 
= query;                            //查询条件,回发后该属性失效
            
            myPage.CreateQuery();        
//生成查询语句        回发后生成的查询语句可以保存。
            myPage.BindFirstPage();        //显示第一页的数据

        }

        
#endregion

    还有两个事件,一般情况下不用处理,这里只是记录使用的时间。
    
private   void  myPage_DataBindBefore( object  s, System.EventArgs e)
        
{
            
//获取记录前的事件
            dt1 = DateTime.Now;
        
        }


        
private   void  myPage_DataBindAfter( object  s, System.EventArgs e)
        
{
            
//绑定控件后的事件
            DateTime dt2 = DateTime.Now;
            
            TimeSpan ts 
= dt2 - dt1;
            Response.Write(ts.Minutes 
+ "");
            Response.Write(ts.Seconds 
+ "");
            Response.Write(ts.Milliseconds  
+ "毫秒");
            
}
    

六、分页控件源代码和演示代码下载
http://www.cnblogs.com/jyk/archive/2008/04/25/1170979.html

需要修改 web.config 里面的连接字符串。
<add key="ConnStr" value="data source=.\tt;initial catalog=NorthWind;persist security info=False;user id=sa;pwd=admin;" />
 


七、核心代码
因为是分页控件,所以呢, 核心代码就是如何分页,也就是分页的算法,使用哪个SQL语句既可以达到很高的效率,又可以满足排序、查询的需求。
 这里针对sql Server 2000 进行了优化,采用两种分页算法。
 第一种算法针对的是一个排序字段,且排序字段没有重复值的情况。
 第二种算法针对的是多排序字段的情况。

 第一种算法的SQL语句
 declare @col int
 set @col =1
 select top {PageSize * (PageIndex - 1) + 1} @col = [排序字段] from TableName
 select top PageSize * from TableName where [排序字段] >= @col

 我知道排序字段不一定都是 int类型的,所以在 第一种算法的时候需要设置一个属性
 myPage.SqlOrderColumnKind = "int";        通过这个属性来修改上面的SQL语句。
 
 第二种算法的SQL语句
 对于这种算法你可能会说,在显示最后一页的时候有问题,这个我也发现了,并且在分页控件里面对最后一页作了修改,已经修证了这个bug。
select [*] from [Table] where [ID] in (
    select top 10 [ID] from
(
         select top 20 [ID] ,AddedDate from [Table]
         order by [AddedDate] desc,[ID]
) as aa order by [AddedDate] ,[ID] desc
)order by [AddedDate] desc,[ID]


八、海量数据测试结果

cpu:xp3000+ 单核
内存:DDR2 1G
硬盘:串口

测试用数据库:SQL Server2000 里的 Northwind 数据库里的 Products 表,就是自带的那个。
显示数据的控件:DataGrid 自动填充字段的方式。

记录数: 2523136
一页显示5条记录。

//分页算法1 单字段排序,且排序字段是聚集索引。
   //1000 页以内 15毫秒
   //10000页以内 30毫秒
   //50000页以内 100多毫秒
   //100000页以内 200多毫秒
   //最后几页 第一次跳转到 4秒多
   //最后几页 连续向前翻页 1秒156毫秒

   //页号大范围跳转的时候需要的时间比较长,但是也小于1秒,同时SQL Server 占用的内存有所增加 120M。最后几页时达到320M

===================================================================
以下是多排序字段的分页情况,排序字段是 UnitPrice,ProductID  

   //分页算法2 无索引  首页 8秒187毫秒 。 
   //10 页以内 2秒812毫秒
   //速度太慢下面的就不测试了

   //分页2 非聚集索引 UnitPrice  首页 468毫秒
   //10 页以内 2秒671毫秒
   //速度太慢下面的就不测试了

   
   //分页算法2 非聚集索引 UnitPrice,ProductID  首页 500毫秒
   //10 页以内 2秒796毫秒
   //100页以内 4秒796毫秒
   //速度太慢下面的就不测试了

   
   //分页算法2 非聚集索引 UnitPrice,ProductID desc  首页 500毫秒
   //10 页以内 0-15毫秒
   //100页以内 15-46毫秒
   //1000页以内 31-62毫秒
   //10000页以内 100毫秒左右
   //50000页以内 400-500毫秒
   //100000页以内 900毫秒左右
   //最后几页 第一次跳转到 4秒421毫秒
   //最后几页 连续向前翻页 4秒375毫秒

   //页号大范围跳转的时候需要的时间比较长,但是也小于1秒,
   //这回SQL Server 占用的内存增加幅度不大 120M左右

        可见设置好索引对于海量数据的分页的重要性


   
相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
4天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
1月前
|
SQL 关系型数据库 MySQL
创建SQL数据库的基本步骤与代码指南
在信息时代,数据管理显得尤为重要,其中数据库系统已成为信息技术架构的关键部分。而当我们谈论数据库系统时,SQL(结构化查询语言)无疑是其中最核心的工具之一。本文将详细介绍如何使用SQL创建数据库,包括编写相应的代码和必要的步骤。由于篇幅限制,本文可能无法达到您要求的2000字长度,但会尽量涵盖创建数
32 3
|
27天前
|
SQL 监控 关系型数据库
SQL错误代码1303解析与处理方法
在SQL编程和数据库管理中,遇到错误代码是常有的事,其中错误代码1303在不同数据库系统中可能代表不同的含义
|
1月前
|
SQL 安全 关系型数据库
SQL错误代码1303解析与解决方案:深入理解并应对权限问题
在数据库管理和开发过程中,遇到错误代码是常见的事情,每个错误代码都代表着一种特定的问题
|
2月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
3月前
|
存储 SQL 安全
【数据库高手的秘密武器:深度解析SQL视图与存储过程的魅力——封装复杂逻辑,实现代码高复用性的终极指南】
【8月更文挑战第31天】本文通过具体代码示例介绍 SQL 视图与存储过程的创建及应用优势。视图作为虚拟表,可简化复杂查询并提升代码可维护性;存储过程则预编译 SQL 语句,支持复杂逻辑与事务处理,增强代码复用性和安全性。通过创建视图 `high_earners` 和存储过程 `get_employee_details` 及 `update_salary` 的实例,展示了二者在实际项目中的强大功能。
41 1
|
2月前
|
SQL 安全 数据库
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
104 0
|
3月前
|
JSON 数据格式 Java
化繁为简的魔法:Struts 2 与 JSON 联手打造超流畅数据交换体验,让应用飞起来!
【8月更文挑战第31天】在现代 Web 开发中,JSON 成为数据交换的主流格式,以其轻量、易读和易解析的特点受到青睐。Struts 2 内置对 JSON 的支持,结合 Jackson 库可便捷实现数据传输。本文通过具体示例展示了如何在 Struts 2 中进行 JSON 数据的序列化与反序列化,并结合 AJAX 技术提升 Web 应用的响应速度和用户体验。
111 0
|
3月前
|
SQL 数据库 索引
SQL 编程最佳实践简直太牛啦!带你编写高效又可维护的 SQL 代码,轻松应对数据库挑战!
【8月更文挑战第31天】在SQL编程中,高效与可维护的代码至关重要,不仅能提升数据库性能,还降低维护成本。本文通过案例分析探讨SQL最佳实践:避免全表扫描,利用索引加速查询;合理使用JOIN,避免性能问题;避免使用`SELECT *`,减少不必要的数据传输;使用`COMMIT`和`ROLLBACK`确保事务一致性;添加注释提高代码可读性。遵循这些实践,不仅提升性能,还便于后期维护和扩展。应根据具体情况选择合适方法并持续优化SQL代码。
52 0
|
3月前
|
SQL Java 数据库连接
【Azure 应用服务】Java ODBC代码中,启用 Managed Identity 登录 SQL Server 报错 Managed Identity authentication is not available
【Azure 应用服务】Java ODBC代码中,启用 Managed Identity 登录 SQL Server 报错 Managed Identity authentication is not available