浅谈分页技术

这几天看到几篇关于分页的文章,觉得有些东西可以分享一下。这里提供一些关于UI分页和数据库分页的一些解决方案。还有一些常用控件的使用方法概要
通常一个查询语句如果得到的数据量过大或者为了UI美观考虑,就需要进行对这些数据进行分页显示。
分页其实有两类,界面上分页和数据库分页。
 
关于数据显示控件
Repeater
 这个是最基本的数据集帮订显示控件。不支持分页
DataList
 比上一个功能要复杂一点,但是也不支持分页
GridView(DataGrid)
 支持分页,功能最强大。效率也是最低的一个。
当然,也可以写自己的分页控件,或者包装一个现有的。
 
数据库分页
 事实上,数据库分页依赖于具体数据库。每种数据库提供的语句不太一样,具体操作要根据具体的数据库才决定。
 比方说sql server : sql server数据分页 比较 http://www.cnblogs.com/dlwang2002/archive/2005/10/14/254971.html
 比方说oracle:它提供了一个RowNum列,所以分页算法很容易实现。Sql server 2005里面也提供了类似的函数。
          string format = "SELECT {0} FROM (SELECT RowNum AS RowIndex, {0} FROM ("
                       + "SELECT {0} FROM {1}{2}{3}) WHERE RowNum <= {4}) WHERE RowIndex > {5}";
 其他的, 比方说
mysql "SELECT * LIMIT {0} OFFSET {1}"
 PostgreSql: "SELECT * LIMIT {0} OFFSET {1}"
       Sqlite: "SELECT * LIMIT {0} OFFSET {1}"
       Firebird: "SELECT FIRST {0} SKIP {1} *"
      DB2: null -- Not Supported
      VistaDB: "SELECT TOP {2}, {0} *"
 
 我现在用的是ORM工具,他支持对常见的各种数据库分页操作。也支持自己写分页扩展。
 
关于分页的方案
1:UI分页,数据库取出所有数据
   这样做的缺点显而易见,不论界面上显示多少,你都是把所有数据都去出来的,至少在内存里面。这个效率的损失就相当严重。
   最经典的DataGrid(.net1.1)的用法就是这样:设置可以分页的属性,取出数据,然后绑定到控件。这样做,其实就是一种全部依赖UI分页的做法
   当然,在DataGrid里面还支持另外一种实现,就是使用虚拟的分页,VirtualPageNumber。自己取出数据有多少页,然后取出其中一页数具进行绑定。这样做就避免了这个缺陷。
   遗憾的是在.net2.o里面,GridView反而没有了这个实现(稍后再说这个问题)
2:UI只显示其中一页,数据库实现分页
   这个就是刚才上边说的DataGrid实现分页的第二种方法。优点是,效率大有提高,特别是数据量比较大的时候。
 
数据分页的简单实现
有了上边的准备,我们来说一下如何实现分页。
1:UI控件的选择
   由于Repeater和DataList本身不支持分页,所以我们如果选择他的话,注定了要自己实现分页了。
我们选择方案当然是第二种分页:数据库分页和界面分页结合的方式。
首先,我们要做的就是为提供Pager. 最简单的,放置几个LinkButtom(<<,<,xx of xxx,>,>>)。这些用来触发命令
                  < asp : LinkButton ID="lb_first" runat="server" OnClick="lb_first_Click"><<</asp:LinkButton>
                  <asp:LinkButton ID="lb_prv" runat="server" OnClick="lb_prv_Click"><</asp:LinkButton>
                  <asp:Label ID="lbl_pager" runat="server" Text="0 of 0"></asp:Label>
                  <asp:LinkButton ID="lb_next" runat="server" OnClick="lb_next_Click">></asp:LinkButton>
              <asp:LinkButton ID="lb_last" runat="server" OnClick="lb_last_Click">>></asp:LinkButton>
然后让你的控件可以识别这些属性:TotalPageCount;CurrentPageIndex,PageSize
剩下的就是写程序每次绑定一下数据了。
    简单的绑定代码:
 1   protected  void  lb_first_Click( object  sender, EventArgs e)
 2      {
 3        this.CurrentPageIndex = 1;
 4        this.BindInspection();
 5    }

 6      protected  void  lb_prv_Click( object  sender, EventArgs e)
 7      {
 8        this.CurrentPageIndex--;
 9        this.BindInspection();
10    }

11      protected  void  lb_next_Click( object  sender, EventArgs e)
12      {
13        this.CurrentPageIndex++;
14        this.BindInspection();
15    }

16      protected  void  lb_last_Click( object  sender, EventArgs e)
17      {
18        this.CurrentPageIndex = this.TotalPageCount;
19        this.BindInspection();
20    }

21     // property
22     private  int  CurrentPageIndex
23      {
24        get
25        {
26            if (Session["CurrentPageIndex"== null)
27                Session["CurrentPageIndex"= 1;
28            return Convert.ToInt32(Session["CurrentPageIndex"]);
29        }

30        set { Session["CurrentPageIndex"= value; }
31    }

32      private  int  TotalPageCount
33      {
34        get
35        {
36            if (Session["TotalPageCount"== null)
37                Session["TotalPageCount"= 1;
38            return Convert.ToInt32(Session["TotalPageCount"]);
39        }

40        set { Session["TotalPageCount"= value; }
41    }

42


   
     
 1            // bind it here
 2
 3            // set property
 4            this .TotalPageCount  =  ps.PageCount;
 5  
 6
 7             if  ( this .CurrentPageIndex  >=  this .TotalPageCount)
 8                  this .lb_next.Enabled  =  false ;
 9              else
10                  this .lb_next.Enabled  =  true ;
11              if  ( this .CurrentPageIndex  <=  1 )
12                  this .lb_prv.Enabled  =  false ;
13              else
14                  this .lb_prv.Enabled  =  true ;
15              this .lbl_pager.Text  =  String.Format( " {0} of {1} " this .CurrentPageIndex.ToString(),  this .TotalPageCount.ToString());
16
17
如果你选择了GridView.没有关系,依然可以使用这种方案。
但是,也有其他选择,那就是使用DataSource控件。我不喜欢用SqlDataSource(觉得把逻辑层高的不清不楚),我一般使用ObjectDataSource.
2:选择适当的数据操作层,用好数据库分页
 刚才提到了,我用的是一个ORM,它提供了这些实现,非常好用。
 
当然,终极解决方法是:做好你的逻辑,不要让每次取出的数据量过大。
 
  http://www.cnblogs.com/dlwang2002/archive/2007/01/10/616736.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值