首先是因为在一些项目中经常要用到分页(真分页),所以我也写一下自己在学习分页中的一些技巧和心得体会。第一次学分页是在学校老师教我们用的一个分页控件"AspNetPager742DLL" 第三方分页插件下载。
数据库的真分页方法有 not in ,max(), row_number() over ()
这是老师教我的 主要是使用存储过程 以及 墟零博客的分页
--------------分页的SQL语句 和获取总条数 ---------------
select ROW_NUMBER()OVER(order by userid) as num, * from [Users] --要分页的表名
select COUNT(*) as totalCount from [Users] ---获取一共查询到了多少条记录
-----------------------------------------------------------------------
---------------------- 分页的存储过程-------------------------
create proc proc_PagerApply
@startRowIndex int, --起始行索引
@maxPageSize int --每页显示多少行
as
with temp as --公式表表达式 with 临时表表名 as
(select row_number() over(order by userid) num,* from [Users])
select * from temp where num between @startRowIndex and @maxPageSize
---------------------------------------------------------------------------------
后台执行存储过程返回DataSet 将 DataSet.Table[0] 绑定到GridView的数据源就可以 首次加载的时候设置起始页每页显示的条数
第二种是我在别人的博客上面看到的 墟零博客的分页
CREATE PROCEDURE [dbo].[UP_GetRecordByPage]
@tblName varchar(255), -- 表名
@fldName varchar(255), -- 排序字段名
@PageSize int = 10, -- 页尺寸 每页显示多少条数据
@PageIndex int = 1, -- 页码
@IsReCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1000) = '1=1' -- 查询条件 (注意: 不要加 where)
AS
declare @begin int ,@end int,@sql varchar(4000),@order varchar(5)
set @begin=@PageSize* (@PageIndex-1) +1
set @end=@begin+@PageSize-1
set @order=''
if(@OrderType=1)
set @order=' desc'
set @sql='
select * from
(
select
ROW_NUMBER() over(order by ' + @fldName + @order +' ) as od,
*
from '+@tblName +'
where ' + @strWhere +
') as tbl
where od between ' + rtrim(ltrim(str(@begin)))+' and ' + rtrim(ltrim(str(@end)))
exec (@sql)
if(@IsReCount=1) --判断传入的参数是否返回分页总条数
exec('select count(*) from '+ @tblName+' where ' +@strWhere)
这是分页的存储过程 UP_GetRecordByPage 是存储过程名 接收 几个参数 可以传入要分页的表名和根据什么字段进行排序
下面这是后台代码
/// <summary>
/// 获取分页的方法
/// </summary>
/// <param name="pageSize"> 每页显示多少条数据</param>
/// <param name="pageIndex">第几页 </param> 点击下一页的时候+1 上一页-1
/// <param name="strWhere">查询条件 可以为空</param>
/// <param name="isCount">是否获取总条数 True False </param>
/// <returns></returns>
public DataSet GetList(int pageSize, int pageIndex, string strWhere, bool isCount)
{
SqlParameter[] parameters = {
new SqlParameter("@tblName", SqlDbType.VarChar, 255), //表名
new SqlParameter("@fldName", SqlDbType.VarChar, 255), //排序字段名
new SqlParameter("@pageSize", SqlDbType.Int), //页尺寸
new SqlParameter("@pageIndex", SqlDbType.Int), //页码
new SqlParameter("@IsReCount", SqlDbType.Bit), //返回记录总数, 非 0 值则返回
new SqlParameter("@OrderType", SqlDbType.Bit), //设置排序类型, 非 0 值则降序
new SqlParameter("@strWhere", SqlDbType.VarChar,1000), //查旬条件
};
parameters[0].Value = "project"; //要分页的表名 可以自己设置定义一个变量接收 DLL传过来的要排序的表名
parameters[1].Value = "projectid"; //排序的字段 也可以 写成变量 用户点击 不同的字段传不同的值
parameters[2].Value = pageSize; //每页显示多少条记录 当前方法接收一个参数进行设置
parameters[3].Value = pageIndex; //当前显示第几页的 数据
//isCount 是否返回查询的总数 如果传进来的是 True 则返回 如果传进来的是 False 则不返回查询总条数
if (isCount)
{
parameters[4].Value = 1;
}
else
{
parameters[4].Value = 0;
}
//默认是降序 可也接收一个参数 是升序还是降序
parameters[5].Value = 0;
//查询条件可以为空
parameters[6].Value = strWhere;
//执行一个带参数的存储过程
//第一个是存储过程名称
//第二个是可变参数名
//第三个是我也不知道
return DbHelperSQL.RunProcedure("UP_GetRecordByPage",parameters,"ds");
}
如果传入的参数是要求返回总条数的话 这个方法的 DataSet结果集里面就会有两个 Tables 查询到的结果
DataSet ds =GetList(5,1,"",True);
this.GridView.DataSource = dsPro.Tables[0]; //结果集里面第一张表 绑定到GridView
this.GridView.DataBind();
int totaCount=Convert.ToInt32(ds.Tables[1].Rows[0][0]); //这是第二个Tables里面查询到的是 总条数
-------------------------------------------------------------
这种是MVC里面的分页方法 这DAL里面用 SQL语句实现的分页 (不是存储过程)
public const int PageCount = 5;//每页多少条数据
/// <summary>
/// 获取项目列表
/// </summary>
/// <param name="pageNo">第几页 </param>
/// <param name="field">排序字段</param>
/// <param name="sort">排序方向</param>
/// <param name="searchCondition">查询条件 </param>
/// <returns></returns>
public static DataSet GetProcList(int pageNo, string field, string sort, string searchCondition)
{
//根据页码和每页有多少条 算出当前页要显示 第几条(开始条数 ) 到 第几条(末尾条数)
int rowNoBegin = (pageNo - 1) * PageCount;
int rowNoEnd = pageNo * PageCount;
//查询 SQl语句
string sql = string.Format(@"select top {0} * from
(
select *,row_number() over (order by ProjectID {4}) RowNumber,
case Status when 0 then '未完成'
when 1 then '完成' end as Stu
from [Project] where 1=1 {5}
) t where 1=1 {5} and RowNumber between {1} and {2} order by {3} {4}",
PageCount, rowNoBegin, rowNoEnd, field, sort, searchCondition);
//{0}:每页有多少条数据
//{1}、{2}:分页的逻辑,该pageNo页是从条数据到第几条数据
//{3}:排序的字段
//{4}:排序的方向
//{5}:查询条件
//查询当前数据总共有多少页 的SQL语句
string sqlPageCount = string.Format(@"select case when count(*)%{1}<>0 then count(*)/{1}+1 else count(*)/{1} end
from (select * from [Project] where 1=1 {0} ) t", searchCondition, PageCount);
//查询当前的数据源总计有多少条数据的SQL语句
string sqlTotalCount = string.Format(@"select count(*) from [Project]");
return SqlHelper.Instance.ExecSqlDataSet(sql + ";" + sqlPageCount + ";" + sqlTotalCount);
}
下面是Ajax通过Get 方法提交到控制器的代码
//绑定数据的通用方法
function getData(pageNo, field, sort, searchCondition) {
$.get("/ProcManager/GetPData?a=" + Math.random(), {
pageNo: pageNo, //页码
field: field, //排序的字段
sort: sort, //排序的方向
searchCondition: searchCondition//查询条件
}, function (text) {
$("#dataGrid").html(text);
$("#currentNo").text(pageNo); //当前第几页
$("#pageCount").text($("#hidPageCount").val()); //总共多少页
$("#totalCount").text($("#hidtotaCount").val()) //总共有多少条记录
});
}
/// <summary>
/// 获取查询列表数据
/// </summary>
/// <returns></returns>
public ActionResult GetPData()
{
string pageNo = Request.QueryString["pageNo"]; //当前显示的 页码
string field = Request.QueryString["field"]; //排序的字段
string sort = Request.QueryString["sort"]; //排序的方向
string searchCondition = Request.QueryString["searchCondition"]; 查询条件
DataSet ds = ProcMangerDAL.GetProcList(int.Parse(pageNo), field, sort, searchCondition);
ViewData["pdata"] = ds;
return View();
}
这个方法返回一个视图到前台 GetDate页面 代码如下
@using System.Data;
@{
Layout = null;
}
<table style="margin-top:10px;" >
<tr>
<th>序号</th>
<th><a class="flsize" href="#" οnclick="sortData('ProjectName');">项目名称</a></th>
<th><a class="flsize" href="#" οnclick="sortData('Stu')">项目状态</a></th>
<th>开始时间</th>
<th>预计完成时间</th>
<th>设置</th>
<th>管理</th>
</tr>
@{
DataSet ds=ViewData["pdata"] as DataSet;
DataTable dt=ds.Tables[0];
int pageCount=Convert.ToInt32(ds.Tables[1].Rows[0][0]);
int totaCount = Convert.ToInt32(ds.Tables[2].Rows[0][0]);
for (int i = 0; i < dt.Rows.Count; i++)
{
<tr>
<td>@dt.Rows[i]["RowNumber"].ToString()</td>
<td οnclick="Proclook('@dt.Rows[i]["ProjectID"].ToString()')">
@dt.Rows[i]["ProjectName"].ToString()
</td>
<td>@dt.Rows[i]["Stu"].ToString()</td>
<td>@dt.Rows[i]["StartTime"].ToString()</td>
<td>@dt.Rows[i]["ForeFinishTime"].ToString()</td>
<td>
<img title="项目成员设置" alt="是" src="../../Content/images/icon_08.gif" οnclick="procSetMan('@dt.Rows[i]["ProjectID"].ToString()')" />
<img title="项目模块设置" alt="" src="../../Content/images/icon_06.gif" οnclick="procModle('@dt.Rows[i]["ProjectID"].ToString()')" />
</td>
<td>
<img title="修改项目" alt="" src="../../Content/images/icon_02.gif" οnclick="editProc('@dt.Rows[i]["ProjectID"].ToString()')" />
<img title="删除项目" alt="" src="../../Content/images/icon_01.gif" οnclick="delectProc('@dt.Rows[i]["ProjectID"].ToString()')" />
</td>
</tr>
}
}
</table>
<input id="hidPageCount" type="hidden" value="@pageCount" />
@*存储当前的数据查询条件的数据的总页数*@
<input id="hidtotaCount" type="hidden" value="@totaCount" />
@*存储当前的数据查询条件的数据总条数*@
这是分页效果
表达能力有限写的不是很好 , 可能写的不好。
我的技术也是菜鸟的水平 现在把我的想法写下来 一起学习共同进步!!!!!