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