一、設計原理闡述

資料查詢分頁,這個功能相信大家都很熟悉,通過資料庫或其它資料來源進行查詢操作後,將獲得的資料顯示到介面上,但是由於資料量太大,不能一次性完全的顯示出來,就有了資料分頁的需求。這個需求在實際開發過程中還是普遍存在的,也給出了不同的實現,正常的的幾種思路有:

1、一次性將所有要查詢的資料查詢出來,然後在客戶端處理,分頁顯示相應的資料。

2、每次只取我所需要的那部分資料,在伺服器端分頁完成後,再傳送到客戶端顯示。

在asp.net中,GridView控制元件自帶的分頁功能,就是引用了第一種思路,但是這個方法有很大的弊端,每次請求都是將所有的資料,一次性的讀入到DataTable或DataSet或其它集合當中,然後再分割槽間顯示出來,顯然造成網路資源的緊張。而如果在伺服器端將資料已經分好頁,再傳送,網路資源顯然壓力大幅度減少,這樣子就提高了查詢的效率。

如果在思路2的基礎上,再進行優化,還可以有以下幾種思路:

1)通過SQL語句分頁

2)引用動態SQL語句進行分頁

3)引用儲存過程進行資料分頁

顯然這裡推薦第3種解決方案,理由是:儲存過程由於在伺服器端資料庫已經預先編譯好,不需要執行時編譯,應該可以直接執行,本身的執行效率比SQL要高;安全性高,防止SQL隱碼攻擊式攻擊(帶引數的SQL語句比簡單的SQL拼接要安全);便於程式碼管理和複用,完全可以直接將儲存過程程式碼儲存起來,在下一個專案中直接引用。

至此,資料查詢分頁原理已經設計完畢,再進一步,可以引用web頁面靜態化技術(不是偽靜態,就是真的生成html檔案),定期的將動態html生成靜態html,這樣可以有效提高頁面的訪問速度,顯然已經不需要每次再到資料庫中查詢了,省去了資料庫查詢和網路資料傳送的時間。

二、程式碼例項

不論是asp、asp.net、jsp、php還是其它web開發語言,涉及到分頁這一塊,原理都是想通的,這裡僅以asp.net為例,完整的設計一個資料查詢分頁功能。

1、完全自己寫分頁程式碼

這個無非就是利用sql語句的分頁功能實現分頁,C#後臺拼接各種字串,這裡不想過多闡述。

2、引用第三方分頁控制元件,比如aspnetpager等

首先新建一個分頁實體類:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MPage
{
    private string pagesql;//產生的sql語句
    private int pagesize;//每頁顯示的條數
    private int pageindex;//顯示頁的索引
                            
    /// <summary>
    /// 產生分頁的sql語句 sql要求必須包含rownum欄位且其別名為rn,如例子:select rownum rn,t.* from test t
    /// </summary>
    public string Pagesql
    {
        get return pagesql; }
        set { pagesql = value; }
    }
                                
    /// <summary>
    /// 每頁顯示的條數
    /// </summary>
    public int Pagesize
    {
        get return pagesize; }
        set { pagesize = value; }
    }
                            
    /// <summary>
    /// 顯示頁的索引 從0開始
    /// </summary>
    public int Pageindex
    {
        get return pageindex; }
        set { pageindex = value; }
    }
}

分頁查詢類:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/// <summary>
/// 獲取分頁的記錄
/// </summary>
/// <param name="page">封裝的頁面物件</param>
/// <param name="result">反饋的結果</param>
/// <returns>結果集的表</returns>
public DataTable GetPageRecord(MPage page, out ArrayList result)
{
    OracleParameter[] oracleParameter = new OracleParameter[6];
                       
    oracleParameter[0] = new OracleParameter("p_pagesql", OracleType.VarChar);
    oracleParameter[0].Direction = ParameterDirection.Input;
    oracleParameter[0].Value = page.Pagesql;
                       
    oracleParameter[1] = new OracleParameter("p_pagesize", OracleType.Number);
    oracleParameter[1].Direction = ParameterDirection.Input;
    oracleParameter[1].Value = page.Pagesize;
                       
    oracleParameter[2] = new OracleParameter("p_pageindex", OracleType.Number);
    oracleParameter[2].Direction = ParameterDirection.Input;
    oracleParameter[2].Value = page.Pageindex;
                       
    oracleParameter[3] = new OracleParameter("p_totalcount", OracleType.Number);
    oracleParameter[3].Direction = ParameterDirection.Output;
                       
    oracleParameter[4] = new OracleParameter("p_pagecount", OracleType.Number);
    oracleParameter[4].Direction = ParameterDirection.Output;
                       
    oracleParameter[5] = new OracleParameter("p_currentpagedata", OracleType.Cursor);
    oracleParameter[5].Direction = ParameterDirection.Output;
                       
    DataAccess da = new DataAccess();
    return da.ExecuteProcedureWithTable(DBConn.sb, ref oracleParameter, "p_app_page"out result);
}

用aspnetpager控制元件和repeater控制元件結合oracle儲存過程繫結:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/// <summary>
/// 用aspnetpager控制元件和repeater控制元件結合oracle儲存過程繫結
/// </summary>
/// <param name="aspnetpager">aspnetpager控制元件</param>
/// <param name="bindingtarget">repeater控制元件</param>
/// <param name="pagesql">執行的sql語句</param>
public void BindingRepeaterWithAspNetPager(AspNetPager aspnetpager, Repeater bindingtarget, string pagesql)
{
    int recordcount = 0;
    ArrayList result = null;
    MPage page = new MPage();
    page.Pagesize = aspnetpager.PageSize;//每頁顯示的條數
    page.Pageindex = aspnetpager.StartRecordIndex / aspnetpager.PageSize;//顯示頁的索引 從0開始
    page.Pagesql = pagesql;//產生分頁的sql語句 sql要求必須包含rownum欄位且其別名為rn,如例子:select rownum rn,t.* from test t
                  
    bindingtarget.DataSource = GetPageRecord(page, out result);
    bindingtarget.DataBind();
                  
    if (result != null && result.Count > 0)
    {
        if (int.TryParse(result[3].ToString(), out recordcount))
        {
            aspnetpager.RecordCount = recordcount;
        }
        else
        {
            aspnetpager.RecordCount = 0;
        }
    }
}

aspnetpager控制元件和repeater控制元件直接繫結datatable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/// <summary>
/// aspnetpager控制元件和repeater控制元件直接繫結Datatable
/// </summary>
/// <param name="aspnetpager">aspnetpager控制元件</param>
/// <param name="bindingtarget">repeater控制元件</param>
/// <param name="dt">Datatable</param>
public void BindingRepeaterWithAspNetPagerByDataTable(AspNetPager aspnetpager, Repeater bindingtarget, DataTable dt)
{
    PagedDataSource pds = new PagedDataSource();
    pds.AllowPaging = true;
    pds.PageSize = aspnetpager.PageSize;
    pds.CurrentPageIndex = aspnetpager.CurrentPageIndex - 1;
    pds.DataSource = dt.DefaultView;
    aspnetpager.RecordCount = pds.DataSourceCount;
             
    bindingtarget.DataSource = pds;
    bindingtarget.DataBind();
}

前臺程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<asp:Repeater ID="Repeater1" runat="server">
               <HeaderTemplate>
                   <table cellpadding="0" cellspacing="0" border="1" width="100%">
                       <thead align="center">
                           <tr>
                               <td style="width: 5%;">
                                   <label>
                                       <b>序號</b></label>
                               </td>
                               <td style="width: 10%;">
                                   <label>
                                       <b>單位程式碼</b></label>
                               </td>
                               <td style="width: 25%;">
                                   <label>
                                       <b>單位名稱</b></label>
                               </td>
                               <td style="width: 8%;">
                                   <label>
                                       <b>單位申報所屬期</b></label>
                               </td>
                               <td style="width: 8%;">
                                   <label>
                                       <b>單位申報基數</b></label>
                               </td>
                               <td style="width: 8%;">
                                   <label>
                                       <b>單位申報個人基數</b></label>
                               </td>
                               <td style="width: 8%;">
                                   <label>
                                       <b>單位應繳總金額</b></label>
                               </td>
                               <td style="width: 8%;">
                                   <label>
                                       <b>單位到帳總金額</b></label>
                               </td>
                               <td style="width: 8%;">
                                   <label>
                                       <b>單位到帳時間</b></label>
                               </td>
                           </tr>
                       </thead>
               </HeaderTemplate>
               <ItemTemplate>
                   <tr align="center" style='background-color: <%#(Container.ItemIndex%2==0)?"#eeeeee":"#ffffff"%>'
                       onmouseover="this.style.background='#ddeeff'" onmouseout="this.style.background='<%#(Container.ItemIndex%2==0)?"#eeeeee":"#ffffff"%>'">
                       <td>
                           <label>
                               <%#Eval("rn") %></label><!--序號-->
                       </td>
                       <td>
                           <label>
                               <%#Eval("dwdm") %></label><!--單位程式碼-->
                       </td>
                       <td>
                           <label>
                               <%#Eval("dwmc") %></label><!--單位名稱-->
                       </td>
                       <td>
                           <label>
                               <%#Eval("dwsbssq") %></label><!--單位申報所屬期-->
                       </td>
                       <td>
                           <label>
                               <%#Eval("dwsbjs") %></label><!--單位申報基數-->
                       </td>
                       <td>
                           <label>
                               <%#Eval("dwsbgrjs") %></label><!--單位申報個人基數-->
                       </td>
                       <td>
                           <label>
                               <%#Eval("dwyjzje") %></label><!--單位應繳總金額-->
                       </td>
                       <td>
                           <label>
                               <%#Eval("dwdzzje") %></label><!--單位到帳總金額-->
                       </td>
                       <td>
                           <label>
                               <%#Eval("dwdzsj") %><!--單位到帳時間 --></label>
                       </td>
                   </tr>
               </ItemTemplate>
               <FooterTemplate>
                   </table>
               </FooterTemplate>
           </asp:Repeater>
           <webdiyer:AspNetPager ID="AspNetPager1" runat="server" AlwaysShow="True" Font-Size="10pt"
               Font-Names="gb2312" CustomInfoHTML="第%CurrentPageIndex%頁 共%RecordCount%條記錄" ShowCustomInfoSection="Right"
               SubmitButtonText="跳轉" TextAfterPageIndexBox="頁" OnPageChanged="AspNetPager1_PageChanged"
               CurrentPageButtonPosition="Center" CustomInfoSectionWidth="45%" CustomInfoTextAlign="Center"
               PageSize="25" ShowPageIndex="True" Width="92%">
           </webdiyer:AspNetPager>