分页解决方案 —— GridView + QuickPager + QuickPager_SQL + DataAccessLibrary + 数据库
?
????這里要說(shuō)的不僅僅是一個(gè)分頁(yè)控件,而是一套解決方案,包括如何顯示數(shù)據(jù)、顯示分頁(yè)導(dǎo)航,如何得到分頁(yè)用的sql語(yǔ)句(等效于存儲(chǔ)過(guò)程),如何提取數(shù)據(jù),如何綁定控件,如何響應(yīng)事件,添加、修改、刪除數(shù)據(jù)后如何更新,如何查詢數(shù)據(jù)等等。一整套完整的解決方案。
?
????這個(gè)方案要有幾個(gè)特點(diǎn):
??????1、支持多種數(shù)據(jù)庫(kù),可以提供多個(gè)分頁(yè)算法以便于支持多種數(shù)據(jù)庫(kù)。
??????2、可以在不同的要求下選用最優(yōu)的分頁(yè)算法。比如如果只需要按照主鍵排序,那么選擇Max分頁(yè)算法無(wú)疑是最快的一種分頁(yè)算法。
??????3、按需所取。不管是哪一種分頁(yè)算法,都要達(dá)到按需所取。假設(shè)一頁(yè)顯示20條記錄,那么從數(shù)據(jù)庫(kù)里面最多只提取20條記錄,不可以多取一條。
??????4、使用簡(jiǎn)單。無(wú)論是更換分頁(yè)算法,更換數(shù)據(jù)庫(kù),還是處理分頁(yè)的事件,都是很簡(jiǎn)單的幾行代碼即可搞定。
??????5、很方便的實(shí)現(xiàn)數(shù)據(jù)查詢的功能。查詢后顯示數(shù)據(jù),查詢后修改、刪除數(shù)據(jù),修改、刪除后重新顯示數(shù)據(jù)等。
??????6、每一個(gè)部分都可以替換。
??????7、支持海量數(shù)據(jù)。無(wú)論數(shù)據(jù)多還是少,都要適合,而且要盡量快。
?
????分頁(yè)解決方案的組成部分
??????顯示數(shù)據(jù)的控件、分頁(yè)控件、分頁(yè)算法、數(shù)據(jù)訪問(wèn)函數(shù)庫(kù)、數(shù)據(jù)庫(kù)?
??????如:GridView + QuickPager + QuickPager_SQL + DataAccessLibrary + SQL Server2000
??????1、顯示數(shù)據(jù)的控件可以是GridView、DetailsView、FormView、Repeater、DataGrid、DataList、CheckBoxList、RadioButtonList等。(控件的繼承關(guān)系可以看這里http://www.cnblogs.com/jyk/archive/2009/04/29/1446033.html?這是.net 里面帶的幾個(gè)常用控件的繼承樹(shù))。也可以支持直接返回DataTable等記錄集。
??????2、分頁(yè)控件,可以是QuickPager也可以是吳旗娃的分頁(yè)控件,也可以是EasyTools等其他的分頁(yè)控件。
??????3、分頁(yè)算法目前還沒(méi)有發(fā)現(xiàn)同類的,硬要算的話,儲(chǔ)存過(guò)程有一點(diǎn)點(diǎn)類似。
??????QuickPager_SQL? 原來(lái)是QuickPager里面的一部分,現(xiàn)在獨(dú)立出來(lái),可以單獨(dú)使用了。
??????4、數(shù)據(jù)訪問(wèn)函數(shù)庫(kù)可以換成SQLHelp、微軟的企業(yè)庫(kù)等,當(dāng)然需要其他的實(shí)現(xiàn)一個(gè)接口(IDALforPager)。
??????5、數(shù)據(jù)庫(kù)可以是Access、Excel、SQL Server,理論上也支持Orcale、MySQL等,只是沒(méi)有安裝這些數(shù)據(jù)庫(kù),所以還沒(méi)有具體實(shí)現(xiàn)。
?
??????(至于ORM嘛,不是太了解,不知道能不能和哪個(gè)部分替換。)
?
??????各個(gè)部分之間的關(guān)系
??????1、QuickPager與QuickPager_SQL
??????這個(gè)就像SqlCommand和SqlConnection的關(guān)系一樣。??????
SqlConnection?cn?=?new?SqlConnection();SqlCommand?cm?=?new?SqlCommand();
cm.Connection?=?cn;
cm.Connection.Open();
?
??????同樣,QuickPager 里面一個(gè)一個(gè)成員的類型就是PagerSQL(也就是QuickPager_SQL)。
??????
??????2、QuickPager與DataAccessLibrary
??????他們是通過(guò)一個(gè)接口(IDALforPager)聯(lián)系在一起的,
??????
Codepublic?interface?IDALforPager
????{
????????///?<summary>
????????///?傳入SQL語(yǔ)句,返回DataTable的接口
????????///?</summary>
????????///?<param?name="sql">SQL語(yǔ)句</param>
????????///?<returns></returns>
????????DataTable?ExecuteFillDataTable(string?sql);
????????///?<summary>
????????///?傳入SQL語(yǔ)句,返回第一條記錄,第一個(gè)字段的值的接口
????????///?</summary>
????????///?<param?name="sql"></param>
????????///?<returns></returns>
????????string?ExecuteString(string?sql);
????????///?<summary>
????????///?記錄出錯(cuò)的描述信息
????????///?</summary>
????????string?ErrorMessage?{?get;?}
???????
????}
?
??????3、QuickPager與顯示數(shù)據(jù)的控件
??????為了便于使用,就是說(shuō)想在使用的時(shí)候盡量的少寫(xiě)代碼,所以我是把顯示數(shù)據(jù)的控件傳遞到了分頁(yè)控件里面,然后在需要綁定控件的時(shí)候,采用as的方式來(lái)判斷是哪種控件,然后在強(qiáng)制轉(zhuǎn)換,最后實(shí)現(xiàn)綁定控件的目的。研究了一下.net里的一些控件的繼承關(guān)系,發(fā)現(xiàn)雖然控件很多,但是我只需要做三次判斷就可以了,這就是基類的好處吧。
Code
private?void?DataBind(System.Web.UI.Control?control,?MarshalByValueComponent?dt)
????????{
????????????if?(control?==?null)
????????????????return;
????????????//為什么沒(méi)有一個(gè)統(tǒng)一的DataSource呢?
????????????BaseDataBoundControl?tmpBaseDataBoundControl?=?control?as?BaseDataBoundControl;
????????????if?(tmpBaseDataBoundControl?!=?null)
????????????{
????????????????tmpBaseDataBoundControl.DataSource?=?dt;
????????????????tmpBaseDataBoundControl.DataBind();
????????????}
????????????else?
????????????{
????????????????Repeater?tmpRepeater?=?control?as?Repeater;
????????????????if?(tmpRepeater?!=?null)
????????????????{
????????????????????tmpRepeater.DataSource?=?dt;
????????????????????tmpRepeater.DataBind();
????????????????}
????????????????else?
????????????????{
????????????????????BaseDataList?tmpBaseDataList?=?control?as?BaseDataList;
????????????????????if?(tmpBaseDataList?!=?null)
????????????????????{
????????????????????????tmpBaseDataList.DataSource?=?dt;
????????????????????????tmpBaseDataList.DataBind();
????????????????????}
????????????????????else
????????????????????{
????????????????????????//不在判斷范圍內(nèi),退出
????????????????????????return;
????????????????????}
????????????????}
????????????}
????????}
?
??????4、QuickPager_SQL與DataAccessLibrary、顯示數(shù)據(jù)的控件沒(méi)有任何關(guān)系。
?
??????5、QuickPager與QuickPager_UI
??????QuickPager_UI 也是分頁(yè)控件的一個(gè)成員,因?yàn)橹辽儆腥N分頁(yè)方式(PostBack、URL、XMLHttp),所以呢我采用了基類和子類的方式來(lái)實(shí)現(xiàn)這種需求,以達(dá)到可以隨時(shí)擴(kuò)展的需求。
??
????分頁(yè)解決方案從使用方法的角度來(lái)說(shuō),有兩種方式。
????????第一種就是“自動(dòng)運(yùn)行”,設(shè)置屬性,其他的就不用管了(僅限于QuickPager,其他的分頁(yè)控件可能不支持);
????????另一種是“手動(dòng)運(yùn)行”,手動(dòng)運(yùn)行就要多做一些事情了(其他分頁(yè)控件的情況)。
?
????分頁(yè)解決方案從提交數(shù)據(jù)的角度,有三種方式。
??????????PostBack、URL、XMLHttp。當(dāng)然這三種也是針對(duì)于QuickPager來(lái)說(shuō)的,其他的分頁(yè)控件是否支持,就看作者的了。
?
????使用方法:
??????時(shí)間比較緊,所以這里先說(shuō)一下使用方法是自動(dòng)運(yùn)行、PostBack的情況。
????????????1、一般顯示數(shù)據(jù)
protected?override?void?OnInit(EventArgs?e)
????????{
????????????base.OnInitComplete(e);
????????????//數(shù)據(jù)訪問(wèn)函數(shù)庫(kù)
????????????DataAccessLibrary?dal?=?DALFactory.CreateDAL();
????????????Pager1.DAL?=?dal;
????????????
????????????//定義QuickPager_SQL
????????????PagerSQL?pagerSQL?=?PagerSQL.Create(PagerSQLKind.MaxMin);
????????????pagerSQL.Page?=?this;
????????????Pager1.ManagerPageSQL?=?pagerSQL;
????????????Pager1.ShowDataControl?=?this.GV;???????//設(shè)置顯示數(shù)據(jù)的控件
????????????
????????}
????????protected?void?Page_Load(object?sender,?EventArgs?e)
????????{
????????????
????????????if?(!Page.IsPostBack)
????????????{
????????????????SetPagerInfo();?????????//設(shè)置表名、字段名等
????????????}
????????}
????????給QuickPager_SQL?設(shè)置屬性,以便拼接SQL#region?給QuickPager_SQL?設(shè)置屬性,以便拼接SQL
????????private?void?SetPagerInfo()
????????{
????????????Pager1.ManagerPageSQL.TableName?=?"News_NewsInfo";??????????//表名或者視圖名稱
????????????Pager1.ManagerPageSQL.TableShowColumns?=?"*";???????????????//需要顯示的字段
????????????Pager1.ManagerPageSQL.TableIDColumn?=?"NewsID";?????????????//主鍵名稱,不支持復(fù)合主鍵
????????????Pager1.ManagerPageSQL.TableOrderByColumns?=?"NewsID";?//排序字段,根據(jù)分頁(yè)算法而定,可以支持多個(gè)排序字段
????????????Pager1.ManagerPageSQL.TableQuery?=?"";??????????????????????//查詢條件
????????????Pager1.PageSize?=?4;????????????????????????????????????????//一頁(yè)顯示的記錄數(shù)
????????}
????????#endregion
????????????2、查詢數(shù)據(jù)
?處理查詢數(shù)據(jù)的情況#region?處理查詢數(shù)據(jù)的情況
????????protected?void?Btn_Search_Click(object?sender,?EventArgs?e)
????????{
????????????//獲取查詢條件
????????????string?query?=?"";
????????????string?tmp?=?"";
????????????tmp?=?this.Txt_Title.TextTrimNone;
????????????if?(tmp.Length?>?0)
????????????{
????????????????if?(query.Length?==?0)
????????????????????query?=?"?title?like?'%"?+?tmp?+?"%'";
????????????????else
????????????????????query?+=?"?and?title?like?'%"?+?tmp?+?"%'";
????????????????
????????????}
????????????//還可以添加其他的查詢條件,這里省略
????????????//給QuickPager_SQL?設(shè)置查詢條件
????????????this.Pager1.ManagerPageSQL.TableQuery?=?query;??//設(shè)置查詢條件
????????????this.Pager1.BindFirstPage();????????????????????//重新綁定控件,顯示第一頁(yè)的數(shù)據(jù)
????????}
????????#endregion
????????????3、添加、修改、刪除后重新顯示數(shù)據(jù)
?添加后重新顯示數(shù)據(jù)#region?添加后重新顯示數(shù)據(jù)
????????protected?void?Btn_Add_Click(object?sender,?EventArgs?e)
????????{
????????????//添加新的數(shù)據(jù)后,顯示第一頁(yè)的數(shù)據(jù)
????????????this.Pager1.BindFirstPage();
????????}
????????#endregion
????????修改數(shù)據(jù)后重新顯示當(dāng)前頁(yè)的數(shù)據(jù)#region?修改數(shù)據(jù)后重新顯示當(dāng)前頁(yè)的數(shù)據(jù)
????????protected?void?Btn_Mod_Click(object?sender,?EventArgs?e)
????????{
????????????//比如在第三頁(yè)修改了一條數(shù)據(jù),修改完畢后,重新顯示第三頁(yè)的數(shù)據(jù)。
????????????this.Pager1.BindThisPage();
????????}
????????#endregion
????????添加后重新顯示數(shù)據(jù)#region?添加后重新顯示數(shù)據(jù)
????????protected?void?Btn_Del_Click(object?sender,?EventArgs?e)
????????{
????????????//比如在第三頁(yè)刪除了一條數(shù)據(jù)后,重新顯示第三頁(yè)的數(shù)據(jù)。
????????????//和修改數(shù)據(jù)后重新顯示的區(qū)別在于,刪除數(shù)據(jù)后需要重新統(tǒng)計(jì)總記錄數(shù),和總頁(yè)數(shù)
????????????this.Pager1.BindThisPageForDelete();
????????}
????????#endregion
?
?
??????
?
??????關(guān)于三層
??????現(xiàn)在三層還是很流行的,那么我的這個(gè)算不算是三層呢?其實(shí)算不算對(duì)于我來(lái)說(shuō)是無(wú)所謂的事情,又沒(méi)有誰(shuí)規(guī)定,現(xiàn)在寫(xiě)項(xiàng)目必須三層(或者MVC),否則就是不合格產(chǎn)品。既然沒(méi)有這個(gè)規(guī)定,那么我又為何要在乎是否可以靠到三層結(jié)構(gòu)上呢?
?
??????另外呀,我覺(jué)得這么寫(xiě)代碼挺簡(jiǎn)單的,要說(shuō)簡(jiǎn)化,還確實(shí)是有簡(jiǎn)化的空間,但是說(shuō)要往三層結(jié)構(gòu)上面靠攏,我還確實(shí)不知道應(yīng)該怎么做。
??????就像http://www.cnblogs.com/wisdomqq/archive/2009/04/29/1446579.html 里說(shuō)的,“經(jīng)常看到有的朋友使用三層結(jié)構(gòu)或者MVC模式,比較生硬,強(qiáng)行進(jìn)行拆分代碼,使得業(yè)務(wù)代碼分散在各個(gè)角落,反而更難閱讀和維護(hù)了。”
???????我覺(jué)得這么寫(xiě),對(duì)于簡(jiǎn)單的應(yīng)用是沒(méi)有什么問(wèn)題的,當(dāng)然了復(fù)雜的情況是有其他的方法來(lái)解決的。
?
代碼下載:
http://www.cnblogs.com/jyk/archive/2008/07/29/1255891.html
?
ps:今天先寫(xiě)這么多,以后再詳細(xì)說(shuō)明。
?
總結(jié)
以上是生活随笔為你收集整理的分页解决方案 —— GridView + QuickPager + QuickPager_SQL + DataAccessLibrary + 数据库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: cga、ega、vga指的是什么
- 下一篇: XI 安装MS SQLSERVER JD