我们今天生活在一个大数据时代,数据量成指数增长。在我们的网页检索数据是往往会检索到太多的数据,但是我们的网页大小又是有限的不能一次性把所有的数据都显示出来,为此分页技术的诞生变得尤为的重要。我在开发一个新闻发布系统的时候,分页技术也是必须的。所以今天我们来简单谈谈一些我们最常用的简单的分页技术。
从分页的方式分,分页技术分为两种,真分页与假分页。那么又什么是个真分页呢?真分页,是指从数据库中每次只检索当前页面所要显示的数据,其他的数据则在其他页面加载时才检索。而假分页,则是从数据库中一次性检索出所有符合条件的数据放入内存,然后再分页显示。简言之,假分页是多次分页检索并显示;真分页,是一次检索,分页显示。那么它们两者又到底谁优,谁劣呢?其实两者各有各的强项。如果,我们检索的数量不大时,假分页就比较占优势了,效率就比真分页要高了。而数据量很大时,则假分页就有些力不从心了,一则检索速度很慢,二则消耗内存资源太多,会大大的降低效率,而真分页则可以很好的解决这个问题。具体原因,很简单,我就不在这里赘述了,大家自己思考。下面具体的我们以几个小例子来说明一下。
在讲分页例子前,我们先来看几个常见的页面数据显示控件,因为我们所有的分页技术必须得配合这些控件才能实现。
Repeater,这个是最基本的数据集绑定显示控件。不支持分页,但是它的效率很高。
DataList ,比Repeater功能要复杂一点,但是也不支持分页。
GridView(DataGrid) ,支持分页,功能最强大,但是也是效率最低的一个。
当然,也可以写自己的分页控件,或者包装一个现有的。
假分页
最典型的例子就是GridView控件实现的分页技术。GridView控件自身就支持分页技术,它早已分页技术的一些方法,属性,事件替我们封装好了,只须我们简单的设置一下它的几个属性,利用它已经封装好的方法,事件,就可以搞定。PageSize属性是GridView控件分页时显示的记录条数,PageIndex属性是指每个分页的索引值,设置了这两个属性,再配上下面的代码就可以实现我们可以的分页效果了。
真分页
在这里举得这个例子,我是利用自定义ASP.net控件配合数据库存储过程来实现的。先封装好ASP.ne控件,然后编译成Dll文件,这样就可以拖入我们的界面使用了(这样我们可以在多处复用我们的该控件。为了方便,这里有我编译好的ASPNetPage,下载到本地添加到VS中的工具箱,拖入界面就可以使用,当然了,网上有关类似这样的控件有很多很多)。接下来就是,编写我们的数据库存储过程了。下面是我编写的存储过程的脚本。
<span style="font-size:18px;">-- ============================================= -- Author: Gelupu -- Create date: 2014-6-20 15:52:08 -- Description: 以分页的形式取出所有新闻 -- ============================================= ALTERprocedure [dbo].[NewsSelectAll] (@pagesize int, @pageindexint, @docountbit) as if(@docount=1) selectcount(*) from News else begin with temptbl as ( SELECTROW_NUMBER()OVER (ORDER BY id desc)AS Row, * from News O ) SELECT * FROM temptbl where Row between(@pageindex-1)*@pagesize+1 and(@pageindex-1)*@pagesize+@pagesize end</span>
参数说明:@pagesize 是用来设置分页显示记录条数的; @pageindex 是用来设置当前页的索引值的; @docount 是通过设置1与非1,来执行存储过程是返回记录数据还是记录条数的。
这是我D层的代码:
<span style="font-size:18px;">namespaceDAL { publicclassNewsDAO { privateSQLHelpersqlhelper; publicNewsDAO() { sqlhelper=newSQLHelper(); } #region 以分页的形式选择全部新闻 /// <summary> /// 选择全部新闻 /// </summary> /// <returns>新闻数据表</returns> publicDataTableSelectAll(intpageSize, intpageIndex, intdoCount) { DataTabledt=newDataTable(); stringsqlText="NewsSelectAll"; SqlParameter[]paras=newSqlParameter[]{newSqlParameter("pagesize",pageSize), newSqlParameter("pageindex",pageIndex), newSqlParameter ("docount",doCount)}; dt=sqlhelper.ExecuteQuery(sqlText, paras,CommandType.StoredProcedure); returndt; } #endregion } }</span>
下面是我的界面层的代码:
<span style="font-size:18px;">publicpartialclassadmin_newsmanager: System.Web.UI.Page { // 页面加载 protectedvoidPage_Load(objectsender, EventArgse) { //判断session里面是否存在管理员 if (Session["admin"]!=null&&Session["admin"].ToString()=="gelupu") { //已登录 if (!Page.IsPostBack) { <span style="color:#FF0000;"> DataTabledt=newNewsManager().SelectAll(anpNewsManager.PageSize,anpNewsManager.CurrentPageIndex, 1); anpNewsManager.RecordCount=(int) dt.Rows[0][0]; BindNews();</span> } } else { //未登录 Response.Redirect("login.aspx"); } } #region绑定新闻列表 privatevoidBindNews() { <span style="color:#FF0000;"> repNews.DataSource=newNewsManager().SelectAll(anpNewsManager.PageSize,anpNewsManager.CurrentPageIndex,0); repNews.DataBind(); </span> } #endregion // 分页按钮 <span style="color:#FF0000;"> protectedvoidanpNewsManager_PageChanged(objectsender, EventArgse) { BindNews(); }</span> }</span>
总结:其实分页技术很简单,并没有大家想的那么难。分页技术有很多,但所有的分页技术都逃不出真分页,假分页这两种,所有的无非就是一些控件与数据库操作的配合实现的。