【9】分页浏览的管理

阅读目录

  • 分页关注的内容

  • 状态的传递

  • 数据的获取

  • 查询结果的分页

  • 跳页的实现

  • 分页器的样式

  • 页面的完整处理流程

回到顶部

分页关注的内容


前面博文中,通过自行构造HTML表格代码,可以生成易于管理、易于扩展的数据列表。但在实际应用中,数据量动则成百上千,单一页面根本无法完全显示所有数据。把所有数据进行分页后逐页显示,是当前比较流行的数据展示方式。因此,我们需要研究和表格方式展示数据相适应的分页管理机制。

分页显示的核心,是根据页面记录数、页号、查询条件、排序顺序等因素,在数据库中查出该页相对应的数据集(DataTable)。按页返回数据集的功能,已经作为一个基本的功能被封装到AccessDB中了,通过AccessDB.GetPage就可以直接获取。因此,我们只需要关心执行查询以外的各种管理和操作,包括以下方面:

  • 获取总记录集的记录数

  • 页码的有效性的检验

  • 查询条件的传递和应用

  • 向任意页面跳转的支持

  • 分页器的样式控制

回到顶部

状态的传递

分页管理的目的就是要对多个相互关联的页面进行管理,这些页面之间存在着联系,因此必须要能够把当前页面的某些重要状态传递给下一个页面。这些状态包括:

  • 数据表名

  • 当前页号

  • 页面大小

  • 当前查询条件

  • 当前排序条件

ASPX有多种方式在页面间传递状态,如Cookie、Session、URL参数等。其中,以URL参数进行状态传递,是当前很多分页工具的普遍做法。综合考虑需求,使用URL传递参数,需要定义以下参数:

  • TableName

  • PageNo

  • PageSize

  • strWhere

  • strOrder

分页的管理在页面中的体现就是分页器,即一组链接按钮和文字信息,通过它们可以了解当前分页信息,进行各种分页的跳转。有了上述的参数定义后,就可以定义分页的几个主要链接的形式。和前面的表格生成工具相一致,我们把分页器的HTML代码生成也封装到一个函数中:


public string GetPager(int pagecount, int currentpage, string urlpara)
{
string strPager = "";
strPager += "<a href=‘?PageNo=1" + urlpara + "‘>首页</a>";
strPager += " <a href=‘?PageNo=" + (currentpage - 1 < 1 ? 1 : currentpage - 1).ToString() + urlpara + "‘>上页</a>";
strPager += " " + currentpage.ToString() + "/" + pagecount.ToString();
strPager += " <a href=‘?PageNo=" + (currentpage + 1 > pagecount ? pagecount : currentpage + 1).ToString() + urlpara + "‘>下页</a>";
strPager += " <a href=‘?PageNo=" + pagecount.ToString() + urlpara + "‘>末页</a>";

return strPager;
}


通过语句调用:

strContent += GetPager(20,1,"");

达到HTML结果如下:


<a href=‘?PageNo=1‘>首页</a> <a href=‘?PageNo=1‘>上页</a> 1/20 <a href=‘?PageNo=2‘>下页</a> <a href=‘?PageNo=20‘>末页</a>

页面显示效果如下:

对于分页器的构造方法而言,需要的参数,就是PageNo而已。但如果页面还有其他的参数,跳转链接应该同时把这些参数传递给下一个页面。因此,我们看到构造方法中有一个urlpara,就是用来传递其他的参数的。

回到顶部

数据的获取

通过传入的参数,就可以进行页面数据的获取了。获取记录的流程是:

取得参数——查询总记录——判断范围,修正页码——查询记录集——构造分页器代码

代码如下:


protected void Page_Load(object sender, EventArgs e)
{
//获取参数
int PageNo = Convert.ToInt32(Request.QueryString["PageNo"]);
int PageSize = 10; //PageSize默认值为10
//获取总记录数
int RecordCount = AccessDB.GetCount("select * from book");
int PageCount = Convert.ToInt32(Math.Ceiling((double)RecordCount / PageSize));
//有效性判断
if (PageNo < 1) PageNo = 1;
if (PageNo > PageCount) PageNo = PageCount;
//查询数据
DataTable dt = AccessDB.GetPage("select * from book",PageSize,PageNo,"ID",false );
//表格
strContent = Formater.FullTable(dt, "ID", "tblsample", "|出版年|书号|", "ID=编号;出版单位=出版社;", true, true, "书名", "showbook.aspx?id=KeyField", "del.aspx", "edit.aspx");
//分页器
strContent += GetPager(PageSize ,PageNo,"");
}

效果显示如下:

上面的分页器的页面大小PageSize被设置为10,可以修改参数或者改造成为任意指定的大小,非常简单就不再详述了。另外,查询语句中,改用GetPage,同时sql语句不再限定条数了。

回到顶部

查询结果的分页

查询是数据管理的一个常用功能,查询浏览界面和数据浏览界面往往是同一个界面,或者说,查询功能本身就是数据浏览的一部分。对于查询的结果,也需要和浏览所有数据记录一致,采用相同的模式进行操作。所以分页管理必须要把查询综合考虑进来。

如果是查询结果分页浏览,和前面的分页浏览有何不同呢?其实很容易看到,就是需要把上面的sql语句,增加一个查询条件即可。因此,查询分页,实质上就是把查询条件作为参数进行传递。

另外,既然把Where子句进行参数传递,顺便把Order子句也进行传递,这样sql的大多数需求就能够满足了。

在实际应用中,查询输入的条件往往是中文的,因此还需要对strWhere进行编码和解码,把中文转换成为URL可以识别的UTF8编码。

对于上面的Demo页面,增加一个查询对话框,如下:

查询按钮处理如下:


//查询按钮事件
protected void Button1_Click(object sender, EventArgs e)
{
strWhere = " and 书名 like ‘%" + TextBox1.Text + "%‘";
SetContent();
}

由于按钮事件的处理是在Page_Load之后,在Page_Load中已经对strContent进行了一次构造,这里必须重新构造strContent,所以把上面的构造方法放到一个单独的函数SetContent中,在Page_Load中调用一次,这里再调用一次,进行覆盖。

另外,参数strWhere是一个页面级的变量,默认为空串,可以把参数保存起来,在调用SetContent时,取得这个参数并构造查询串。


string strSQL = "select * from book";

if (strWhere == "") //没有最近的查询动作,检查有没有传递的参数
{
if (Request.QueryString["strWhere"] != null)
strWhere =HttpUtility.UrlDecode( Request.QueryString["strWhere"].ToString());
}
strSQL += " where 1=1" + strWhere;

//...

//分页器
strContent += GetPager(PageCount, PageNo, "&strWhere="+HttpUtility.UrlEncode(strWhere));


上面代码中,strWhere有可能有多种情况:

  • 默认方式打开,为空串

  • 单击查询后的处理,为刚才设定的条件

  • 从分页器的链接传递而来,但是优先级要低于查询的条件

下图是查询“名著”的结果,进行分页浏览的第四页,下方状态栏是鼠标放到“下页”的链接信息:

回到顶部

跳页的实现

除了按顺序浏览,很多页面数量往往非常巨大,因此分页器还需要支持跳页,可以向任意页面跳转。由于通过URL参数进行控制,实际非常简单,参数一修改即可。实现则需要通过js来实现。


strPager += "<input name=‘GotoNum‘ type=‘text‘ id=‘GotoNum‘/><a href=\"#\" onclick=\"var url=document.URL;var gn=document.getElementById(‘GotoNum‘).value;if(gn!=‘‘){if(url.indexOf(‘PageNo=‘)==-1){url=url +(url.indexOf(‘?‘)==-1?‘?‘:‘&‘)+ ‘PageNo=‘+gn;}else{ url=url.replace(‘PageNo=‘, ‘PageNo=‘+gn+‘&wy=‘); }window.navigate(url);}\" >跳转</a>";

这样构造出的分页器就具备了跳转功能了!

回到顶部

分页器的样式

分页功能几乎是每个数据管理页面都需要的,但其样式总的来说,不会有太多的变化,因此,写好一个通用性较强的样式,就可以到处使用了。这是一个常用的分页器样式。


<style type="text/css"">
/** 分页 **/
.pager{width:770px;text-align:center;margin:10px 0 10px 0;position:absolute;bottom:0px;}
.pager a{display:inline-block;font-size:12px; width:40px; background-color:#FFFFFF;padding:3px;text-align:center;border:1px #CCCCCC dotted;margin:0px 0px 2px 2px;}
.pager a:link,a:visited{ text-decoration:none;}
.pager a:hover{text-decoration:underline; background-color:#FF99FF;}
.pager #GotoNum{width:30px;}
.pager #reccount,.pager #pageinfo{display:inline-block;margin:0 5px 3px 5px;font-weight:bold;}
</style>

加上这个分页器后,将页面代码放到.pager的div中,效果如下:

回到顶部

页面的完整的处理流程

以下是页面的完成处理流程代码:


public partial class book_pager_query : System.Web.UI.Page
{
protected string strContent;
string strWhere="";
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
SetContent();
}
private void SetContent()
{
string strSQL = "select * from book";

if (strWhere == "") //没有最近的查询动作,检查有没有传递的参数
{
if (Request.QueryString["strWhere"] != null)
strWhere =HttpUtility.UrlDecode( Request.QueryString["strWhere"].ToString());
}
strSQL += " where 1=1" + strWhere;

//获取参数
int PageNo = Convert.ToInt32(Request.QueryString["PageNo"]);
int PageSize = 10; //PageSize默认值为10
//获取总记录数
int RecordCount = AccessDB.GetCount(strSQL);
int PageCount = Convert.ToInt32(Math.Ceiling((double)RecordCount / PageSize));
//有效性判断
if (PageNo < 1) PageNo = 1;
if (PageNo > PageCount) PageNo = PageCount;
//查询数据
DataTable dt = AccessDB.GetPage(strSQL, PageSize, PageNo, "ID", false);
//表格
strContent = Formater.FullTable(dt, "ID", "tblsample", "|出版年|书号|", "ID=编号;出版单位=出版社;", true, true, "书名", "showbook.aspx?id=KeyField", "del.aspx", "edit.aspx");
//分页器
strContent +="<div class=pager>"+ GetPager(PageCount, PageNo, "&strWhere="+HttpUtility.UrlEncode(strWhere))+"</div>";
}
public string GetPager(int pagecount, int currentpage, string urlpara)
{
string strPager = "";
strPager += "<a href=\"?PageNo=1" + urlpara + "\">首页</a>";
strPager += " <a href=\"?PageNo=" + (currentpage - 1 < 1 ? 1 : currentpage - 1).ToString() + urlpara + "\">上页</a>";
strPager += " " + currentpage.ToString() + "/" + pagecount.ToString();
strPager += " <a href=\"?PageNo=" + (currentpage + 1 > pagecount ? pagecount : currentpage + 1).ToString() + urlpara + "\">下页</a>";
strPager += " <a href=‘?PageNo=" + pagecount.ToString() + urlpara + "‘>末页</a>";

strPager += "<input name=‘GotoNum‘ type=‘text‘ id=‘GotoNum‘/><a href=\"#\" onclick=\"var url=document.URL;var gn=document.getElementById(‘GotoNum‘).value;if(gn!=‘‘){if(url.indexOf(‘PageNo=‘)==-1){url=url +(url.indexOf(‘?‘)==-1?‘?‘:‘&‘)+ ‘PageNo=‘+gn;}else{ url=url.replace(‘PageNo=‘, ‘PageNo=‘+gn+‘&wy=‘); }window.navigate(url);}\" >跳转</a>";

return strPager;
}
//查询按钮事件
protected void Button1_Click(object sender, EventArgs e)
{
strWhere = " and 书名 like ‘%" + TextBox1.Text + "%‘";
SetContent();
}
}

GetPager的通用性较强,所以已经集成到CommonCode中了,通过Pager对象可以访问。

时间: 2024-10-06 11:32:37

【9】分页浏览的管理的相关文章

Linux基础三:linux目录结构和目录文件的浏览、管理及维护

目录文件的浏览.管理及维护(一) 1.Linux文件系统的层次结构 1)Linux文件系统的树状结构:在Linux或UNIX操作系统中,所有的文件和目录都被组织成一个以根节点开始的倒置的树状结构. 2)目录的定义:目录相当于Windows中的文件夹,目录中存放的既可以是文件,也可以是其他的子目录. 3)顶层根目录的表示:使用“/”来表示根目录 4)文件系统中的两个特殊目录: . 表示当前目录,即用户所在的工作目录 .. 表示父目录,即当前目录的上一层目录 2.Linux系统中的一些重要的目录 1

PHP搜索MYSQL数据库加分页浏览小结

PHP搜索加分页浏览小结: 1 分页后再做搜索 2 这里对于url的拼接,以及模糊查询,搜索时候的显示添加,SQL语句的拼接 3 对于页面传递过来的超级链接的变量,如果不存在就要设置,对于可能抛出异常的要加上@屏蔽错误 4 对于查询一般用一些关键字来获取 5 分页显示的limit条件要写好 6 搜索时候的where条件 搜索表单: <!--- 搜索表单---> <form action="list3.php" method="get"> 标题

操作系统之分页式内存管理2

1.分页的内存管理克服了交换系统的缺点:外部碎片,程序不能大于物理内存等.但付出的代价是页面更换.在交换系统下,一个程序作为一个整体加载到内存,这样,在程序运行时,无须在从磁盘上加载任何东西,而分页系统下,一个程序的所有页面不一定都在内存中,所以可能会产生缺页中断,缺页中断的服务程序负责把位于磁盘上的数据加载到物理内存中来,如果物理内存中有空闲的页面,那就直接使用空闲的页面,但如果物理内存已满,就需要挑选某个已经使用过的页面进行替换.这里就出现一个问题,如何挑选? 2.如果挑选的页面是之后很快又

第四单元 目录文件的浏览、管理及维护(一)

第四单元 目录文件的浏览.管理及维护(一) Linux文件系统的层次结构 Linux文件系统的树状结构 目录是什么 顶层根目录的表示 文件系统中的两个特殊目录 Linux系统中的一些重要的目录 bin目录 sbin目录 家目录 dev目录 etc目录 挂载目录/media或/mnt 其他常用目录 绝对和相对路径 绝对路径 相对路径 课后作业 [本节内容]1. Linux文件系统的层次结构(详见linux系统管理P40)1) 了解Linux文件系统的树状结构:在Linux或UNIX操作系统中,所有

操作系统之分页式内存管理1

1.分页内存管理的核心就是:页面的翻译. 对于任何一个虚拟页面,系统要知道该页面是否在物理内存中?如果在的话,对应的物理页面是哪一个?如果不在,就会产生一个缺页中断,并将该虚页从磁盘转到内存,然后将分配给它的物理页面号返回.虚拟页面到物理页面的映射,这个翻译过程由内存管理单元MMU完成.MMU接收CPU发出的虚拟地址,将其翻译为物理地址后发给内存.MMU对虚拟地址的翻译只是对页面号的翻译,而对于偏移值则不进行任何操作,这是因为虚拟页表和物理页表大小完全一样,虚拟页面里的偏移值和物理页面里的偏移值

Hibernate+SpringMVC+Spring+分页实现留言管理项目

项目结构: 这里使用到了Mysql数据库 所用到的包:略. 首先进行springmvc.xml的配置,注意数据库密码要改为自己的. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema

目录文件的浏览、管理及维护(二).作业

1) 开启Linux操作系统,要求以root用户登录GNOME图形界面,右击桌面打开终端 2) 使用命令切换到root用户的家目录 3) 确定当前用户所在的工作目录 4) 创建目录wg 5) 使用绝对路径的方法在wg目录下新建文件a.txt 6) 进入wg目录 7) 使用相对路径的方法在当前目录下新建目录和b.txt文件 8) 以长列表格式列出当前目录下的内容 9) 删除空目录wg01 10) 进入上一级工作目录 11) 强制删除非空目录wg 12) 复制/etc/passwd到当前目录,名为f

WebForm分页浏览

1.封装类 //封装类 using System; using System.Collections.Generic; using System.Web; /// <summary> /// Users 的摘要说明 /// </summary> public class Users { private string _UserName; public string UserName { get { return _UserName; } set { _UserName = valu

五.目录,文件的浏览,管理和维护

一.linux文件系统的层次结构: a)在linux中,所有的文件和目录都被组织成一个由一个根结点的树状结构,如 mkdir -p /a/b/c/d ,用tree 命令查看能直观显示目录的结构为树状结构 b)目录中可以有文件,也可以有子目录. c) . 表示当前所在的目录,.. 表示父目录,即当前目录的上一层目录 2.linux重要的目录 a)bin目录:用来存放常用的可执行文件 b)sbin 目录:用来存放系统的可执行文件 c)家目录:用来存放自己的文件或目录,其中,超级用户root的家目录为