做新聞發布系統的時候,以為視頻中沒有講解分頁實現的部分,於是自己花了一天時間寫,當然過程中錯誤不斷,還好一邊學習一邊解決終於做出來了。後來又看了視頻中實現的方法,跟自己有點不同,這裡分享一下自己的經驗。
當要顯示資料量足夠大的時候,我們往往採用分頁顯示的處理辦法。分頁有真分頁和假分頁。
假分頁:從資料庫中取出所有的資料,然後分頁在介面上顯示。訪問一次資料庫,但由於選擇的資料量比較大,所以第一次花費時間比較長,但之後每一頁的顯示都是直接、快速的,避免對資料庫的多次訪問。
真分頁:確定要顯示的數量和內容,然後每次都去資料庫取出該少量資料,優點是資料量小,缺點是訪問資料庫頻繁。在大型網站中往往採用真分頁,比如百度的圖片擷取。
新聞發布系統採用真分頁。Web層用AspNetPager控制項和Repeater控制項顯示。實現思路是這樣的:
查詢所有新聞的記錄總數,從而得到AspNetPager的RecordCount屬性值。設定PageSize屬性,確定每頁顯示的記錄條數。以上兩個屬性就可以確定所有這些記錄要分多少頁顯示。由控制項的StartRecordIndex和EndRecordIndex屬性可以確定當前頁要顯示的記錄起止索引號,從而可以方便的從資料庫中查詢。查詢得到的datatable即為repeater繫結資料源。
這裡用到的控制項屬性和視頻中不同,故sql語句也有所不同。
看下代碼實現:
Web前端:
<webdiyer:AspNetPager ID="anp" runat="server" FirstPageText="首頁" LastPageText="尾頁" NextPageText="下一頁" PrevPageText ="上一頁" OnPageChanged="anp_PageChanged" PageSize="5" AlwaysShow="true"></webdiyer:AspNetPager>
後台代碼:
if (!Page.IsPostBack) { anp.RecordCount = nm.Count(); BindNews(); }
protected void anp_PageChanged(object sender, EventArgs e) { BindNews(); } #region 綁定新聞列表 private void BindNews() { int startIndex = anp.StartRecordIndex; int endIndex = anp.EndRecordIndex; DataTable dt= nm.SelectToPage(startIndex, endIndex); repNews.DataSource = dt; repNews.DataBind(); } #endregion
D層:
/// <summary>分頁選擇新聞 /// /// </summary> /// <param name="startIndex">選定頁的第一條新聞索引</param> /// <param name="endIndex">選定頁的最後一條新聞索引</param> /// <returns>選定頁的新聞內容</returns> public DataTable SelectToPage(int startIndex, int endIndex) { DataTable dt = new DataTable(); SqlParameter[] paras = new SqlParameter[] { new SqlParameter ("@startIndex",startIndex ), new SqlParameter("@endIndex",endIndex) }; string sql = "select * from (select ROW_NUMBER() over (order by id desc) as row,T.* from news T) as TT where TT.row between @startIndex and @endIndex"; dt = sqlhelper.ExecuteQuery(sql, paras, CommandType.Text); return dt; } /// <summary>新聞總數 /// /// </summary> /// <returns></returns> public int Count() { string sql = "select count(*) from news"; DataTable dt = new DataTable(); dt = sqlhelper.ExecuteQuery(sql,CommandType.Text); int count = Convert.ToInt32(dt.Rows[0][0].ToString()); return count; }
這裡有兩點要注意的地方:
第一,在查詢新聞總數時,要調用sqlhelper的不帶參數的查詢方法得到一個只有一行一列的表,開始我以為是返回一個數值,掉錯了方法,在D層中取出表中的第一行第一列返回到B層就可以了。
第二,添加控制項出錯。
如果引用無誤,頭部有註冊源碼,重新編譯甚至重啟VS後錯誤提示依然存在,那麼運行時是不影響的,暫時先這樣吧。哪位高手知道原因,還請不吝賜教。