• 我自己写的一个分页控件(源码和演示代码)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  = 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();        //显示第一页的数据

            }


        查询情况,点击查询按钮后需要做的事情。这里只是作了一个演示,可以增加更多的查询条件
        
    实现查询功能

        还有两个事件,一般情况下不用处理,这里只是记录使用的时间。
        
    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左右

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


       
  • 相关阅读:
    leetcode Super Ugly Number
    leetcode Find Median from Data Stream
    leetcode Remove Invalid Parentheses
    leetcode Range Sum Query
    leetcode Range Sum Query
    leetcode Minimum Height Trees
    hdu 3836 Equivalent Sets
    hdu 1269 迷宫城堡
    hud 2586 How far away ?
    poj 1330 Nearest Common Ancestors
  • 原文地址:https://www.cnblogs.com/jyk/p/1175808.html
Copyright © 2020-2023  润新知