混在web上,那有不同分頁打交道的,分頁偏偏又是一個硬傷,總是不能找到一個通用的解決方法,即使用上分頁自定義/用戶控件感覺還是少了點什麼,性能。
web頁面一次一般顯示10行數據為好,但往往很多時候我們從數據庫中查出來上萬條數據,這個時候我們要在上萬條數據中顯示10條,那就必須分頁。分頁的第一問題就是分頁數據。
1.分頁數據:分頁的數據分為兩種,一種是在數據庫中只取需要的10條數據,這也是性能提升的標致,一種是全盤拖出,放到程序緩存中再用程序來分頁。
1.1 第一種取數據方式有select top [PageSize] * from [Table] where id not in(select top [CurrentPage-1] [PageSize] id from [Table] ----用於Access,mssql當中
另一種是存儲過程,這也是最快的取數據方式
ALTER PROCEDURE GetAuthors上面這段存儲過程是仿微軟的寫法,微軟在Membership裡面采用也是這存儲過程分頁。
其他數據庫取數據也有不同,sql2005有行號函數,Oracle也有,MySQL就更好取了limit 10,20
1.2第二種就是全部數據取出來再做緩存,數據用程序處理,.ado/jdbc有定位法,Adapter.Fill()用這個填充需要的數據,GridVIEw自定義分頁事件就是使用這個,看到很多自定義控件也使用這種方式。
2.分頁采取何種方式了,現在網頁都講究SEO,所以在前台分頁的時候我摒棄PostBack方式,而采用URL方式.不采PostBack也就不需要用到VIEwState[“PageNo”]存取數據,每次分頁的時候都重新加載,所以視圖狀態就沒撒用.
好了,現在很清楚,為了效率,為了SEO,混口飯吃真不容易,數據采用存儲過程從數據庫中取所需的數據,並返回總共條數.分頁采用URL方式,一是為了urlRewrite和SEO,至於postback提倡在後台分頁,畢竟方便。
那現在就到了實現階段,數據顯示控件肯定是Repeater/DataList/GridVIEw統殺.剛開始我是想把分頁控件和數據顯示在一起,但是若使用存儲過程傳遞參數比較麻煩,不使的存儲過程參數個數是不一樣的,所以決定采用數據顯示和分頁控件分離的方法,分頁控件只傳遞總記錄數就可以了.
所以即想當爹又當媽,那是很累的,現在主要使用存儲過程從數據庫取出所需的數據,分頁控件又采用URL,到止分頁效率高了,SEO也實現了,但是三層架構中不好使,三層架構中要傳參中加頁碼也可以使,代碼如下
這是頁面代碼:
public partial class PagerDemo : System.Web.UI.Page這是用戶控件代碼:
Code
public partial class Pager : System.Web.UI.UserControl
{
private int _totalRecords;
private int _pageSize = 10;
private int _maxPagesShown = 10;
private System.Collections.Generic.List<string> queryString;
protected void Page_Load(object sender, EventArgs e)
{
SetPages();
}
public int TotalRecords
{
get { return _totalRecords; }
set { _totalRecords = value; }
}
public int PageIndex
{
get
{
return Request.QueryString["PageNo"] == null ? 1 : int.Parse(Request.QueryString["PageNo"]);
}
}
public int PageSize
{
get { return _pageSize; }
set { _pageSize = value; }
}
public int MaxPagesShown
{
set { _maxPagesShown = value; }
}
public int PageCount
{
get { return TotalRecords / PageSize + 1; }
}
private void SetPages()
{
Panel1.Controls.Clear();
HyperLink link;
if (PageIndex - _maxPagesShown > 1)
{
link = new HyperLink(); link.Text = "<<"; link.NavigateUrl = MakeLink("1"); Panel1.Controls.Add(link);
}
if (PageIndex > 1)
{
link = new HyperLink(); link.Text = "<"; link.NavigateUrl = MakeLink(PageIndex - 1); Panel1.Controls.Add(link);
}
for (int i = PageIndex - _maxPagesShown; i <= PageIndex + _maxPagesShown; i++)
{
if (i > 0 && i <= PageCount)
{
if (PageIndex == i)
{
link = new HyperLink(); link.Text = "Page " + i.ToString(); link.CSSClass = "selected"; Panel1.Controls.Add(link);
}
else
{
link = new HyperLink(); link.Text = i.ToString(); link.NavigateUrl = MakeLink(i); Panel1.Controls.Add(link);
}
}
}
if (PageIndex < PageCount)
{
link = new HyperLink(); link.Text = ">"; link.NavigateUrl = MakeLink(PageIndex + 1); Panel1.Controls.Add(link);
}
if (PageIndex + _maxPagesShown < PageCount)
{
link = new HyperLink(); link.Text = ">>"; link.NavigateUrl = MakeLink(PageCount); Panel1.Controls.Add(link);
}
}
private string MakeLink(Object pageID)
{
string currentPageID = pageID.ToString();
queryString = new System.Collections.Generic.List<string>();
foreach (string key in Request.QueryString.Keys)
{
if (key != "PageNo")
{
queryString.Add(key + "=" + Request.QueryString[key]);
}
}
queryString.Add("PageNo=" + pageID.ToString());
string filePath = Request.CurrentExecutionFilePath;
return String.Format(filePath + "?{0}", String.Join("&", queryString.ToArray()));
}
}
我將代碼打包,歡迎下載,給出意見.../Files/izxp/Pager.rar
Copy Right By Robo_zou