做新闻发布系统的时候,以为视频中没有讲解分页实现的部分,于是自己花了一天时间写,当然过程中错误不断,还好一边学习一边解决终于做出来了。后来又看了视频中实现的方法,跟自己有点不同,这里分享一下自己的经验。
当要显示数据量足够大的时候,我们往往采用分页显示的处理办法。分页有真分页和假分页。
假分页:从数据库中取出所有的数据,然后分页在界面上显示。访问一次数据库,但由于选择的数据量比较大,所以第一次花费时间比较长,但之后每一页的显示都是直接、快速的,避免对数据库的多次访问。
真分页:确定要显示的数量和内容,然后每次都去数据库取出该少量数据,优点是数据量小,缺点是访问数据库频繁。在大型网站中往往采用真分页,比如百度的图片获取。
新闻发布系统采用真分页。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后错误提示依然存在,那么运行时是不影响的,暂时先这样吧。哪位高手知道原因,还请不吝赐教。