關於分頁控制項的文章

2021-09-05 19:17:37 字數 4164 閱讀 2801

原文:

其實關於分頁方面的,以前在csdn裡面也發過幾個帖子。

現在整理一下。

分頁控制項正式命名為 mypage 。

版本號:2.0.0.1

framework:.net2.0

webform  (b/s)

支援多種資料庫,分頁演算法,提取資料的方式都可以替換。

分頁,自從做b/s的專案起,就和分頁打起了交到,一開始使用usercontrol來做,很粗糙,也沒有什麼效能可言。但是分頁又是不可避免的,一次提取全部的資料,咱用的資源太多,吃不消。於是乎就在不斷的想辦法,一是操作簡單,一是效能要好。

想要操作簡單就要封裝成自定義控制項,要想效能好就要研究資料庫的特點,sql語句的分頁演算法,最最重要的就是要設定好合理的索引!往往索引是最重要的,但同時往往又是被忽略的。

於是一方面研究自定義伺服器控制項如何編寫,一面研究如何寫sql語句才能讓提取資料更快,由於一直在使用sql server2000,所以分頁演算法也都是圍繞這個資料庫轉的。04年底終於初步實現了,至少自己用起來還是很順手的。也就是在這時候發現了吳旗娃的分頁控制項。於是進行了一下對比:

這樣做的有點就是:靈活。適用於多種資料來源,甚至是xml檔案,也可以自由選擇分頁演算法,這樣做確實是很靈活,但是隨之而來的缺點就是:繁瑣。

對於只針對資料庫來分頁的情況,每次分頁的時候,都要再寫點提取資料的**,真是麻煩。我很懶,自然不願意接受這種情況,我要做到,只寫幾行簡單的**就可以實現分頁的全部功能!我可以接受分頁控制項只能對sql server進行分頁,只使用datatable來傳遞資料,但是在呼叫的時候一定要簡單簡單再簡單。

於是我的分頁控制項(mypage)不僅負責ui的繪製,還要負責sql語句的生成(根據屬性組合sql語句),還要到資料庫裡提取資料(當然這個功能要交給資料訪問函式庫來實現),最後還要能夠自動處理翻頁時產生的事件,自動繫結控制項。

以前的版本是基於 .net1.1編寫的,主要的**結構是04年底確定的,以後只是小修小補,一直未作大的改動,因為一直都可以使用,沒有太大的問題。現在vs2008已經出來好久了,應該公升級了。既然公升級那麼就公升得徹底一點,不僅僅是把**拷貝到vs2008裡面,重新編譯一邊就ok了(這樣做確實可以一次編譯成功),要藉此機會徹底改變一下結構。

和吳旗娃的分頁控制項相比,以前的分頁控制項確實是缺乏靈活性,對多種資料庫支援的不好,分頁演算法也不能靈活的更換和自由編寫,只能用datatable來承載資料,postback分頁和url分頁也是使用了兩個控制項來實現。一切看起來都是很混亂的(不過很奇怪,執行起來卻沒有什麼問題)。

既然知道了有這麼多的缺點,那麼就要在公升級的時候一一改正。按照職責分工,設定乙個類負責ui的繪製,在設定乙個類負責分頁用得分頁演算法,在設定乙個類來負責提取資料,最後把這幾個類作為分頁控制項的成員,這樣就可以互相呼叫,自由替換。結構圖如下。

好像有點過度設計的嫌疑,我也在想,用得著這麼費事嗎?真的需要這麼寫嗎?

(等等,這麼看怎麼有點像三層的結構,pageui有點像ui層,pagesql算是邏輯層吧(分頁嘛,如何寫sql語句,這個可以算作是一種邏輯吧,如果不算的話也沒什麼),pagegetdata就是資料訪問了,當然還需要乙個資料訪問函式庫,不過這個是分頁控制項外面的。我可不想寫得像三層那樣的麻煩。呵呵。)

不過我也沒有想把所有的資料庫的所有可能的分頁演算法都寫到資料庫裡,可以在分頁控制項的外面繼承pagesql類來寫乙個子類,在這個子類裡面實現需要的分頁演算法,然後把這個例項賦值給分頁控制項就ok了。

mypage.managerpagesql = yoursql;

當然了,如果不給這個屬性複製的話,分頁控制項會生成乙個預設的pagesql例項來自動賦值。pageui和pagegetdata也可以使用同樣的方法換成適合自己的的要求例項(實現方法)。

幾個誤區:

1、儲存過程。不是說使用了儲存過程就代表著高效,那要看儲存過程內部是什麼樣子的,如果儲存過程內部採用組合sql語句的方法,那麼就喪失了儲存過程最大的優勢:快取執行計畫!試想,在儲存過程裡面組合sql語句,你讓sql server,如何儲存執行計畫呢?如果不能儲存,那麼和在程式裡面組合sql語句,然後提交給資料庫有什麼區別呢?

我看到網上很多介紹分頁演算法的文章,大部分都是直接給出乙個儲存過程,在這個儲存過程裡面組合sql語句,要知道,看這樣的**是多麼的鬱悶呀。

當然,你可以為了能夠快取執行計畫而乙個表使用乙個儲存過程,就像吳旗娃的**裡提供的那個生成儲存過程的模板提供的儲存過程, 但是這樣有很多的問題:會增加很多的儲存過程、查詢條件不容易靈活設定(查詢字段越多越不好編寫)、公升級資料庫(包括公升級分頁演算法)。

什麼東東多了都是不好管理的,試想乙個資料庫裡有500個儲存過程,其中100個是用來分頁的,100個是用來新增資料的,100個等等,是不是比較亂呢?

查詢,在做企業定製開發的程式的時候,最常聽到的就是,你把列表裡的所有欄位都設定為可以查詢的吧,而且可以多欄位一起查詢。呵呵,二、三十個欄位在儲存過程裡面寫成查詢的方式,不太容易吧,而且需求還很很頻繁的變化。

以前的專案使用sql server2000 ,現在 sql server2005出來了,是不是要公升級了,以前使用表變數(或者其他方式)的分頁方式,聽說05裡面使用row_number()效率更高,編寫起來也更容易,是不是要換一下呢?這個操作不太好做吧。

而是用分頁控制項的形式就方便多了,因為是在分頁控制項內部組合分頁演算法的,只要保持屬性(tabletname等)不變就可以了,用這些屬性幾乎和一組合成任意的分頁演算法,不怕資料庫的公升級、演算法的更換。

( 這就是我的分頁控制項不採用儲存過程的原因。)

2、索引。要想提高分頁的效率,必須要設定好索引,包括非聚集索引在內。

索引在介紹分頁演算法的文章裡,提到的機率並不多。並不是說只有在海量資料的情況下才需要索引,在資料量不多的情況下,有的是有也是需要的。

前兩天就遇到了乙個,六七個表關聯在一起,主表有一萬多條記錄(也是記錄最多的表),關聯比較多和複雜(有兩個表需要使用兩個關聯字段,否則會出現重覆記錄),查詢條件也比較多,而且還要使用三個欄位來排序。這三個欄位又不在同乙個表裡面。

一開始記錄不太多的情況,速度很快,後來記錄達到一萬多條以後,前幾頁也是比較快的,這是客戶想要看看效率,就看了一下最後幾頁,這下慘了,五六秒鐘之後才反映過來。反覆試了幾次確實很慢。這點資料量不會這麼慢吧,想要說服客戶也不是太容易(畢竟一條記錄才五六個字段,加起來不超過20個字),還是自己想辦法吧。

開啟查詢分析器,拷貝檢視裡得sql語句,然後檢視執行計畫,暈了,好多好多,乙個乙個看吧,好多都是可以利用索引來查詢資料的,有乙個需要全表掃瞄,占用了46%。就拿他下手吧,其實現在還不能完全看懂執行計畫的圖都表是什麼意思,只能跟著感覺瞎猜。最後給最後乙個排序欄位加了乙個非聚集索引(好像還給乙個欄位加了乙個非聚集索引),問題解決了,檢視最後幾頁,在兩秒中內就可以顯示出來資料(區域網)。這樣可與也基本可以接受了。其實正式使用的時候,都會通過查詢條件先過濾資料的。所以只要前100頁能夠很快顯示出來就可以了。

所以,要想提高分頁的效率,一定要先想辦法設定好合理的索引。

我查了一下字典,page有翻頁的含義,而pager是bp機、網路尋呼機的意思,不知道為什麼有乙個人的分頁控制項叫做 mypager。不管別人是怎麼想的了,我的這個不算重名吧。

mypage 的使用方法

protected void page_load(object sender, eventargs e)

} private void setpageinfo()

不要怕,不用給所有的屬性都賦值的,至少給

mypage.controlgridid

mypage.tablename

mypage.tableordercolumns

這是那個屬性賦值,然後執行mypage.bindfirstpage();    就可以了。

先寫這些吧,有些頭暈了,呵呵。

(在網頁的下面)

請注意後面的引數。

在webconfig裡面修改連線字串和資料庫型別。datatype ---- 1: ms sql ;2:oledb;3:odbc。

直接看原始碼:

目前sql server2005 使用的分頁演算法

set nocount on;

with t_pager as (

select *,rn = row_number() over (order by id desc) from test_indexorder )

select id,name,content,co1,co2,co3,co4,co5 from t_rn where rn between 19007 and 19057;

大文章的分頁

前面有篇文章介紹了 asp.net長文章採用分隔符進行分頁 但是如果分頁中含有html標記還是很容易出現問題的,比如在fck中插入 page 自定義的分頁符 後,往往會把成對的 或標記隔開導致網頁布局混亂。不料fck自帶插入分頁符功能,使用fckeditor中的分頁符後就可以完美解決長文章的分頁問題...

長篇文章的分頁

region 對於長篇文章的分頁 根據每頁顯示的字數分 string articlecontent changesize dr artic content tostring 載入全文 int contentlength articlecontent.length 計算全文長度 const int p...

長篇文章分頁

public string nohtml string htmlstring 去除html標記 public string outputbysize string p strcontent 分頁函式 else if request.querystring pages null catch set t...