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

温馨提示: 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  = ;                //一页显示的记录数
            myPage.IsOrderDesc = true;                //倒序显示记录
            
            //查询条件
            myPage.SqlQuery = "";                            
            
            //查询条件,回发后再次执行 myPage.CreateQuery() 的时候,会把 SetQuery 添加到 SqlQuery 里。
            myPage.SetQuery = "";                            
            
            myPage.CreateQuery();        //生成查询语句        回发后生成的查询语句可以保存。
            myPage.BindFirstPage();        //显示第一页的数据

        }

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

private void SetPage2()
        {
            //多排序字段的分页方式
            //支持多字段排序。

            myPage.SetSQLKind = "";                //设置分页算法
            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  = ;                                //一页显示的记录数

            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 > )
                query = "ProductName like '%" + tmp + "%'";

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

                if (query.Length ==)
                    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左右

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据库

使用VBA创建Access数据表

导读: 本期介绍如何在Access数据库中创建一张空数据表。下期将介绍如何将工作表中的数据存入数据库对应的表中,随后还将介绍如何从数据库的表中取出数据输出到Ex...

28970
来自专栏陈本布衣

SQLite 带你入门

SQLite数据库相较于我们常用的Mysql,Oracle而言,实在是轻量得不行(最低只占几百K的内存)。平时开发或生产环境中使用各种类型的数据库,可能都需要...

44850
来自专栏hotqin888的专栏

golang beego orm无限条件查询,多条件查询,不定条件查询,动态多条件查询sql语句,一个字段匹配多值

其实我的需求就是:一个树状目录,每个目录下都存有成果,给定某一个上级目录id,分页查询出这个目录下以及子孙目录下的所有成果,要求分页。

1.1K20
来自专栏Web 开发

在SAE上开发遇到的问题~

添加一个escape_data()的函数,该函数已经会自动识别各种PHP配置环境~

12600
来自专栏零基础使用Django2.0.1打造在线教育网站

利用Flask搭建微电影视频网站(二):项目优化与模型设计

努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!

70110
来自专栏Java帮帮-微信公众号-技术文章全总结

第二十七天 数据库基础&JDBC使用&工具类Properties&连接池&DBUtils【悟空教程】

第二十七天 数据库基础&JDBC使用&工具类Properties&连接池&DBUtils【悟空教程】

15520
来自专栏逸鹏说道

SQL Server 存储过程的几种常见写法分析

最近发现还有不少做开发的小伙伴,在写存储过程的时候,在参考已有的不同的写法时,往往很迷茫, 不知道各种写法孰优孰劣,该选用那种写法,以及各种写法优缺点,本文以一...

43180
来自专栏Java3y

JDBC【事务、元数据、改造JDBC工具类】

1.事务 一个SESSION所进行的所有更新操作要么一起成功,要么一起失败 举个例子:A向B转账,转账这个流程中如果出现问题,事务可以让数据恢复成原来一样【A账...

36480
来自专栏Java帮帮-微信公众号-技术文章全总结

day26.MySQL【Python教程】

14560
来自专栏更流畅、简洁的软件开发方式

【自然框架】QuickPagerSQL——专门生成分页用的SQL的类库

   分享一个生成分页用SQL的函数库   一般一提到分页,大家就会想到存储过程,而大多数情况都是在存储过程里面拼接SQL,我觉得与其在存储过程里面拼接,还不如...

27750

扫码关注云+社区

领取腾讯云代金券