用AjaxPro实现无刷新翻页效果及数据库分页技术介绍

在看本文之前,建议查看本人的系列文章:
《AjaxPro与服务器端交互过程中如何传值》:http://blog.****.net/zhoufoxcn/archive/2008/01/05/2026908.aspx
《用AjaxPro实现二级联动》:http://blog.****.net/zhoufoxcn/archive/2008/01/07/2029204.aspx
《用AjaxPro实现定时刷新效果》:http://blog.****.net/zhoufoxcn/archive/2008/03/09/2160407.aspx
以便对AjaxPro有个初步印象。

题外话:经不住一些朋友的一再要求,一气写了这么几篇Ajax方面的文章,这其中大部分代码都是从我的项目中摘取出来的,不过为了演示整个程序的框架结构,所以在演示程序代码里不会有大量与实际相关的业务逻辑处理,但是这并不妨碍你利用这些理论做出复杂的、完善的应用。

一、数据库分页理论
在实际项目中经常会遇到一个表里有几K、几M以上的数据,而呈现给用户时并不会一下子都显示出来,所以都是分批展示给用户,这样一来可以减小网络传输量,二来也减轻服务器压力。

通常在不同数据库中都有查询从第N条到第M条记录的方法(M>N>=0),不过其效率和性能都不太一样。假如有如下一个表:

DROPTABLEIFEXISTS`zhoufoxcn`.`userlist`;
CREATETABLE`zhoufoxcn`.`userlist`(
`UserId`
int(10)unsignedNOTNULLauto_increment,
`UserName`
varchar(45)NOTNULL,
`Age`
int(10)unsignedNOTNULLdefault'10',
`Sex`
tinyint(3)unsignedNOTNULLdefault'1',
`Tall`
int(10)unsignedNOTNULL,
`Salary`
int(10)unsignedNOTNULL,
PRIMARYKEY(`UserId`)
)ENGINE
=InnoDBAUTO_INCREMENT=694DEFAULTCHARSET=utf8;
以上是我今天演示要用到的一个MySQL中的表,对于同样结构的表,查询从第N条到第M条记录的方法在MySQL中表示为:
select*fromuserlist order by userId limit n,m
MS SQL Server:
selecttop(m-n)*fromuserListwhereuseridnotin
(
selecttopnuseridfromuserListorderbyuserid)orderbyuserid
Oracle:
select*from(selectrownumno,*fromuserlistwhererownum<=m)whereno>=n;

另外,如果数据量小的话还可以直接用DbDataAdapter 的子类的实例的public int Fill (int startRecord,int maxRecords,params DataTable[] dataTables)方法。如果数据量大的话,可能会根据实际情况采用临时表或者缓存的办法,来获得更高性能。

二、程序代码:
前台页面:

<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="AjaxPager.aspx.cs"Inherits="AjaxPager"%>

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
<title>AjaxPro翻页效果</title>
<styletype="text/css">
tr.items
{
background-color
:#8FACC2;
border-color
:#FFFFFF;
line-height
:18px;
}
tr.table
{/*表格内容*/
background-color
:#F1F3F5;
border-color
:#FFFFFF;
line-height
:18px;
}
</style>
</head>
<bodyonload="JumpPage(1)">
<formid="form1"runat="server">
<tableborder="0"cellpadding="1"cellspacing="1">
<tr><td>和谐小区青年居民概况表</td></tr>
<tr><td>
<divid="memberList">
数据装载中,请等待.....
</div>
</td></tr>
<tr><td>说明:本名单中不包括离退休人员、残疾智障人员和儿童。</td></tr>
</table>
</form>
<scriptlanguage="javascript"type="text/javascript"defer="defer">
varpageSize=20;//假定每页显示20条数据
functionJumpPage(page)//完全服务器端分页处理方法
{
varlabel=document.getElementById("memberList");
label.innerHTML
=AjaxPager.GetString(parseInt(page),parseInt(pageSize)).value;
}
/*
functionShowPager()
{
}

functionJumpPageClient(page)
{
varlabel=document.getElementById("memberList");
vardata=AjaxPager.GetDataTable(parseInt(page),parseInt(pageSize)).value;
if(data!=null)
{
alert(data.Rows.length);
}
label.innerHTML=data.Rows.length;

}
*/
</script>
</body>
</html>
后台代码:
usingSystem;
usingSystem.Data;
usingSystem.Configuration;
usingSystem.Collections;
usingSystem.Web;
usingSystem.Web.Caching;
usingSystem.Web.Security;
usingSystem.Web.UI;
usingSystem.Web.UI.WebControls;
usingSystem.Web.UI.WebControls.WebParts;
usingSystem.Web.UI.HtmlControls;
usingSystem.Text;
usingMySql.Data.MySqlClient;
usingMySql.Data.Types;

///<summary>
///说明:本文介绍如何利用AjaxPro技术实现翻页时局部刷新,同时也介绍了翻页所涉及到的数据库知识(MySQL、MSSQL和Oracle)。
///本演示程序采用MySQL数据库,数据库中的数据是采用程序随机生成的。
///首发地址:http://blog.****.net/zhoufoxcn/archive/2008/03/12/2174234.aspx
///作者:周公
///日期:2008-3-12
///</summary>
publicpartialclassAjaxPager:System.Web.UI.Page
{
protectedvoidPage_Load(objectsender,EventArgse)
{
AjaxPro.Utility.RegisterTypeForAjax(
typeof(AjaxPager));
}

///<summary>
///从数据库中指定位置读取指定数目的数据
///</summary>
///<paramname="startIndex">记录的起始页位置</param>
///<paramname="size">要读取的记录条数</param>
///<returns></returns>
[AjaxPro.AjaxMethod]
publicDataTableGetDataTable(intpageIndex,intsize)
{
MySqlConnectionconnection
=newMySqlConnection(ConfigurationManager.ConnectionStrings["MySql"].ConnectionString);
MySqlDataAdapteradapter
=newMySqlDataAdapter("select*fromuserlistlimit"+(pageIndex-1)*size+","+size,connection);
DataTabledata
=newDataTable();
adapter.Fill(data);
connection.Close();
adapter.Dispose();
returndata;
}
///<summary>
///传递div节点的html字符串
///</summary>
///<paramname="startIndex">记录的起始页位置</param>
///<paramname="size">要读取的记录条数</param>
///<returns></returns>
[AjaxPro.AjaxMethod]
publicstringGetString(intpageIndex,intsize)
{
StringBuildertext
=newStringBuilder();
text.Append(
"<tableborder='0'cellpadding='0'cellspacing='0'width='520px'>");
text.Append(
"<trclass='items'align='center'>");
text.Append(
"<tdstyle='width:80px'>编号</td>");
text.Append(
"<tdstyle='width:80px'>姓名</td>");
text.Append(
"<tdstyle='width:80px'>年龄</td>");
text.Append(
"<tdstyle='width:80px'>性别</td>");
text.Append(
"<tdstyle='width:80px'>身高</td>");
text.Append(
"<tdstyle='width:80px'>工资</td>");
text.Append(
"</tr>");
DataTablesource
=GetDataTable(pageIndex,size);
DataRowrow;
for(inti=0;i<source.Rows.Count;i++)
{
row
=source.Rows[i];
text.Append(
"<trclass='table'align='center'>");
for(intcolumn=0;column<source.Columns.Count;column++)
{
text.Append(
"<tdstyle='width:80px'>"+row[column].ToString()+"</td>");
}
text.Append(
"</tr>");
}
intpageCount=(int)(Math.Ceiling(GetRecordCount()/(double)size));
text.Append(
"<trclass='items'align='center'>");
text.Append(
"<td><ahref='javascript:JumpPage(1)'>首页</a></td>");
if(pageIndex<pageCount)
{
text.Append(
"<td><ahref='javascript:JumpPage("+(pageIndex+1)+")'>下一页</a></td>");
}
else
{
text.Append(
"<td>下一页</a></td>");
}
if(pageIndex>1)
{
text.Append(
"<td><ahref='javascript:JumpPage("+(pageIndex-1)+")'>上一页</a></td>");
}
else
{
text.Append(
"<td>上一页</a></td>");
}
text.Append(
"<td><ahref='javascript:JumpPage("+pageCount+")'>尾页</a><td>");
text.Append(
"<td>当前页:"+pageIndex+"/"+pageCount+"</td>");
text.Append(
"</table>");
returntext.ToString();
}
///<summary>
///返回记录总条数
///</summary>
///<returns></returns>
[AjaxPro.AjaxMethod]
publicintGetRecordCount()
{
MySqlConnectionconnection
=newMySqlConnection(ConfigurationManager.ConnectionStrings["MySql"].ConnectionString);
MySqlCommandcommand
=newMySqlCommand("selectcount(userId)fromuserlist",connection);
connection.Open();
intcount=int.Parse(command.ExecuteScalar().ToString());
connection.Close();
command.Dispose();
returncount;
}
}

程序的运行效果:
用AjaxPro实现无刷新翻页效果及数据库分页技术介绍

用AjaxPro实现无刷新翻页效果及数据库分页技术介绍

用AjaxPro实现无刷新翻页效果及数据库分页技术介绍

最后说明:细心的朋友也许还会发现程序中public DataTable GetDataTable(int pageIndex, int size)也有AjaxMethod属性,我原本打算将这个方法写完的,可是现在时间太晚,留待大家实现了。这也就是另外一种办法:向客户端返回一个DataTable,在客户端将DataTable内的数据加工一下,它与我现在展示的方法区别是一个在服务器端、一个在客户端实现拼接div层的innerHtml方法。在服务器拼接的优点是纯cs代码,开发效率高,但是较真地说它占用了服务器资源;在客户端拼接的办法的优点就是拼接时不占用服务器资源,运行效率高,但是编写的时候效率较低。