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

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: 温馨提示: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
相关文章
|
1月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
1月前
|
SQL 存储 PHP
解决高版本laravel/framework中SQLServer2008分页报错问题
【11月更文挑战第15天】在高版本的Laravel框架中,使用SQLServer 2008数据库进行分页操作时可能会遇到兼容性问题,导致报错。本文提供了两种解决方案:一是升级数据库版本至2012或更高,以提高对复杂查询的支持;二是通过自定义分页查询构建器,手动调整分页逻辑,使其适应SQLServer 2008的特性。具体实施步骤包括备份数据、安装新数据库版本、恢复数据,或创建自定义分页查询类并在模型中使用。这些方法能有效解决分页报错问题。
|
1月前
|
SQL PHP 数据库
解决高版本laravel/framework中SQLServer2008分页报错问题
【11月更文挑战第6天】在高版本的 `laravel/framework` 中使用 SQL Server 2008 进行数据库操作时,可能会出现分页报错。这是由于 `laravel` 的分页机制与 SQL Server 2008 的某些特性不兼容所致。解决方法包括:1. 升级数据库版本;2. 自定义分页查询语句;3. 使用兼容包或插件;4. 修改 `laravel` 的分页逻辑。
|
2月前
|
SQL 关系型数据库 MySQL
创建SQL数据库的基本步骤与代码指南
在信息时代,数据管理显得尤为重要,其中数据库系统已成为信息技术架构的关键部分。而当我们谈论数据库系统时,SQL(结构化查询语言)无疑是其中最核心的工具之一。本文将详细介绍如何使用SQL创建数据库,包括编写相应的代码和必要的步骤。由于篇幅限制,本文可能无法达到您要求的2000字长度,但会尽量涵盖创建数
112 3
|
2月前
|
SQL 监控 关系型数据库
SQL错误代码1303解析与处理方法
在SQL编程和数据库管理中,遇到错误代码是常有的事,其中错误代码1303在不同数据库系统中可能代表不同的含义
|
2月前
|
SQL 安全 关系型数据库
SQL错误代码1303解析与解决方案:深入理解并应对权限问题
在数据库管理和开发过程中,遇到错误代码是常见的事情,每个错误代码都代表着一种特定的问题
|
4月前
|
存储 SQL 安全
【数据库高手的秘密武器:深度解析SQL视图与存储过程的魅力——封装复杂逻辑,实现代码高复用性的终极指南】
【8月更文挑战第31天】本文通过具体代码示例介绍 SQL 视图与存储过程的创建及应用优势。视图作为虚拟表,可简化复杂查询并提升代码可维护性;存储过程则预编译 SQL 语句,支持复杂逻辑与事务处理,增强代码复用性和安全性。通过创建视图 `high_earners` 和存储过程 `get_employee_details` 及 `update_salary` 的实例,展示了二者在实际项目中的强大功能。
47 1
|
3月前
|
SQL 分布式计算 大数据
大数据开发SQL代码编码原则和规范
这段SQL编码原则强调代码的功能完整性、清晰度、执行效率及可读性,通过统一关键词大小写、缩进量以及禁止使用模糊操作如select *等手段提升代码质量。此外,SQL编码规范还详细规定了代码头部信息、字段与子句排列、运算符前后间隔、CASE语句编写、查询嵌套、表别名定义以及SQL注释的具体要求,确保代码的一致性和维护性。
113 0
|
3月前
|
SQL 安全 数据库
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
174 0
|
4月前
|
JSON 数据格式 Java
化繁为简的魔法:Struts 2 与 JSON 联手打造超流畅数据交换体验,让应用飞起来!
【8月更文挑战第31天】在现代 Web 开发中,JSON 成为数据交换的主流格式,以其轻量、易读和易解析的特点受到青睐。Struts 2 内置对 JSON 的支持,结合 Jackson 库可便捷实现数据传输。本文通过具体示例展示了如何在 Struts 2 中进行 JSON 数据的序列化与反序列化,并结合 AJAX 技术提升 Web 应用的响应速度和用户体验。
139 0