分页,大家很非常熟悉的内容,不会上网的小朋友都知道;咱们看书的时候,就有了分页,其实我个人觉得,网站对内容的分页,其实也是根据书上的这个分页设想出来的,觉得一页的内容太多了,应该分页出来,给人不一样的感觉。其实我们写文章的分段也是一样,分段要多点,让读者很快就能阅读完一段,这对读者的心理上来说,是一个很大心理成就,相信大家也不愿意看到一篇文章过来,密密麻麻的,找不到分段,那这样的文章,我想是卖不出去的。也就是只能留着自己看了,也许自己也不敢看。
那么站在用户的角度来想,那这个分页是必须要有的,除非你确定你的内容能最多在鼠标划一下就能看完的内容之内(其实我是试着去看了一下百度,百度是鼠标滑下来一点点就能看到下面的分页序列了,也许对于别的分辨率不一样,但是也差不多吧)。我们看看一些比较厉害的搜索引擎:

我总感觉这个效果特别好,这样大家都不用数里边有多少个O了,第一次用google的时候,就喜欢上了这个,分页都做的设置的这么别致;当然百度也不错:

这看起来很普通,其实很多网站都差不多是这样的普通的分页,给用户一种熟悉的感觉,也挺好;CSDN也是一样:

那么我们今天也来试着模拟这个分页:
假分页:从数据库中选择所有的记录后再进行分页。
使用GridView控件来达到分页的功能:
我们在test1.aspx里边拖进来一个GridView控件:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test1.aspx.cs" Inherits="WebApplication1.test1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>分页测试</title>
</head>
<body>
<form id="form1" runat="server">
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
onpageindexchanging="GridView1_PageIndexChanging" PageSize="5">
</asp:GridView>
</form>
</body>
</html>
我们进行一下数据的绑定。
/*
*创建人:陈宗毅
*创建时间:2012年8月24日
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BLL;
namespace WebApplication1
{
public partial class test1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack )
{
BindNews();
}
}
private void BindNews()
{
GridView1.DataSource = new B_Page().SelectAll();
GridView1.DataBind();
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
BindNews();
}
}
}我们还要设置一下GridView的一些属性:

那么我们来看看这个效果,前提是数据库里边咱们要有数据让代码来读取。

这样我们就轻而易举的实现了分页的功能。他的一个非常大的优点就是设计简单,除了绑定就剩两句话而已;但是这个缺点也是很明显的,咱们这个SelectAll是选择全部的新闻,那么这个分页是每次分页都选择出全部的新闻,咱们做的这个测试是几条新闻而已,要是真正发布的系统,新闻数量就达到几万条甚至几十万条,那么每次分页都要选择出全部的新闻,那整个系统就会显得特别特别的慢,就会导致用户无法忍受你选择新闻所花费的时间,这种分页方式:把数据从数据库中全部选择出来,然后再进行分页;这种分页就是咱们经常说的,假分页。
真分页:只从数据中选择当前页的记录。换句话说:我们想要什么就拿什么,避免了多拿的现象。
我们先看一下这个控件怎么使用:AspNetPager
我们来看看这边的代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test1.aspx.cs" Inherits="WebApplication1.test1" %>
<%@ Register assembly="AspNetPager" namespace="Wuqi.Webdiyer" tagprefix="webdiyer" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>分页测试</title>
</head>
<body>
<form id="form1" runat="server">
<webdiyer:AspNetPager ID="anp" runat="server" onpagechanged="anp_PageChanged"
PageSize="5">
</webdiyer:AspNetPager>
</form>
</body>
</html>
我们让他显示一下记录数:
/*
*创建人:陈宗毅
*创建时间:2012年8月24日
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BLL;
namespace WebApplication1
{
public partial class test1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack )
{
anp.RecordCount = 22;
}
}
protected void anp_PageChanged(object sender, EventArgs e)
{
Response.Write("开始记录数:"+anp.StartRecordIndex+"<br>结束记录数:"+anp.EndRecordIndex);
}
}
}
那么效果是这样的:

然后剩下的就是导入咱们的数据库内容了,但是我们遇到了一个问题,看看我们的数据库:

我们看到这里的id和序号是不对应的,那么我们分页需要的是序号,那么我们必须想办法把序号提前出来,那么我们的数据库有了这么一种办法,我们看看:
select ROW_NUMBER() over (order by id desc)as 行号, * from news那么我们再来看看这个效果:

这个效果就是我们把那个序号提取出来了,就是行号。
那么我们要取6~10条记录,我们在数据库这么写:
with temptabl as(
select ROW_NUMBER() over (order by id desc)as 行号, * from news
)
select * from temptabl where 行号 between 5 and 10我们就能把5~10条记录提取出来了:

这也就差不多完成了。我们接下来写一个存储过程:
create PROCEDURE [dbo].[proc_FenYE]
@tblName varchar(255), -- 表名
@strGetFields varchar(1000) = '*', -- 需要返回的列,默认*
@strOrder varchar(255)='', -- 排序的字段名,必填
@strOrderType varchar(10)='ASC', -- 排序的方式,默认ASC
@PageSize int = 10, -- 页尺寸,默认10
@PageIndex int = 1, -- 页码,默认1
@strWhere varchar(1500) = '' -- 查询条件 (注意: 不要加 where)
AS
declare @strSQL varchar(5000)
if @strWhere !=''
set @strWhere=' where '+@strWhere
set @strSQL=
'SELECT * FROM ('+
'SELECT ROW_NUMBER() OVER (ORDER BY '+@strOrder+' '+@strOrderType+') AS pos,'+@strGetFields+' '+
'FROM '+@tblName+' '+@strWhere+
') AS sp WHERE pos BETWEEN '+str((@PageIndex-1)*@PageSize+1)+' AND '+str(@PageIndex*@PageSize)
exec (@strSQL)
GO那么我们的SQLhelper里边:
/// <summary> 返回执行的SQL语句的第一行第一列的值
///
/// </summary>
/// <param name="sql">SQL语句</param>
/// <returns></returns>
public string ExecuteScalar(string sql)
{
try
{
cmd = new SqlCommand(sql, GetConn());
object obj = cmd.ExecuteScalar();
if (obj != null)
{
return obj.ToString();
}
return "";
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
}
}我们的DAL里边写一个FenYeDAO:
/// <summary>根据条件计算新闻记录数
///
/// </summary>
/// <param name="cond">条件,不用加where</param>
/// <returns></returns>
public int CalcCount(string cond)
{
string sql = "select count(*) from news";
if (!string.IsNullOrEmpty(cond))
{
sql += "where" + cond;
}
return int.Parse( sqlhelper.ExecuteScalar(sql));
}BLL里边:FenYeManager.cs:
/// <summary>根据条件计算新闻记录数
///
/// </summary>
/// <param name="cond">条件,不用加where</param>
/// <returns></returns>
public int CalcCount(string cond)
{
return ndao.CalcCount(cond);
}我们在测试文件里边test.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test1.aspx.cs" Inherits="WebApplication1.test" %>
<%@ Register Assembly="AspNetPager" Namespace="Wuqi.Webdiyer" TagPrefix="webdiyer" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>分页测试</title>
<link href="css/pager.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<webdiyer:AspNetPager ID="anp" runat="server" PageSize="5"
OnPageChanged="anp_PageChanged"
CustomInfoHTML="总计%RecordCount%条记录,共%PageCount%页"
FirstPageText="首页" LastPageText="尾页" NextPageText="下一页" PrevPageText="上一页"
ShowCustomInfoSection="Left" ShowPageIndexBox="Never"
CssClass="pages" CurrentPageButtonClass="cpb"
>
</webdiyer:AspNetPager>
</div>
</form>
</body>
</html>
在后台test.aspx.cs代码里边绑定一下:
/*
*创建人:陈宗毅
*创建时间:2012年8月24日
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BLL;
namespace WebApplication1
{
public partial class test : System.Web.UI.Page
{
BLL.NewsManager nm = new BLL.NewsManager();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack )
{
anp.RecordCount = nm.CalcCount("") ;
BindGV();
}
}
//分页事件
protected void anp_PageChanged(object sender, EventArgs e)
{
BindGV();
}
//绑定新闻列表
private void BindGV()
{
int pagesize = anp.PageSize;
int pageindex = anp.CurrentPageIndex;
GridView1.DataSource = nm.Select(pagesize, pageindex, "");
GridView1.DataBind();
}
}
}最后我们加上那个迅雷的风格,那么效果如下:

呵呵,其实分页也没那么难,对自己有信心,就能做好。
本文介绍了网页分页的两种常见方法:假分页和真分页。假分页通过获取所有数据再进行客户端分页,简单但效率低下;真分页则直接从数据库获取指定页数据,提高性能。文中通过ASP.NET的GridView控件和AspNetPager控件展示了如何实现这两种分页,并提供了存储过程示例。

1200

被折叠的 条评论
为什么被折叠?



