一、设计原理阐述
数据查询分页,这个功能相信大家都很熟悉,通过数据库或其它数据源进行查询操作后,将获得的数据显示到界面上,但是由于数据量太大,不能一次性完全的显示出来,就有了数据分页的需求。这个需求在实际开发过程中还是普遍存在的,也给出了不同的实现,正常的的几种思路有:
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
>
|