第一部分:项目中使用分页代码流程
1.外层方法判定
在程序中,需要在顶层方法中判定前端传入的分页实体是否为空,每页记录数对不对(即合法性判定)
if (pageInfo == null) pageInfo = new PaginationEntity { PageIndex = 1, PageSize = 1000 };
if (pageInfo.PageSize > 1000 || pageInfo.PageSize <= 0) pageInfo.PageSize = 1000;
2.内层方法判断后赋值
然后在实现方法中对需要跳过的记录数,每页记录数(需要获取的记录就介于这两者之间,不包含需要跳过的记录数,但是包含当页最后一条记录),需要排序的字段进行
设置
int pageSkip = 0;
int pageSize = 0;
string defaultOrderby = "DealTime asc";
if (pageInfo != null)
{
if (pageInfo.PageSize > 0) pageSize = pageInfo.PageSize;
if (pageInfo.PageIndex > 0) pageSkip = (pageInfo.PageIndex - 1) * pageInfo.PageSize;
if (!string.IsNullOrEmpty(pageInfo.OrderBy)) defaultOrderby = pageInfo.OrderBy;
}
3.分页脚本
在脚本中,使用:
SELECT * FROM
(
select q.*, row_number() OVER (ORDER BY q.{0}) AS row_num, count(1) over () as recordcount FROM
(
select ...
from ...
) q
) WHERE row_num >{0} and ROWNUM <= {1}
其中,{0}为排序字段(包含正序asc还是逆序desc),{1}为pageSkip,{2}为pageSize
4.总记录数赋值给分页实体
if(resultEntityList != null && resultEntityList.count > 0)
{
pageInfo.RecordCount = resultEntityList.First().RecordCount; //不能使用resultEntityList.count,这个只是当页记录数,不是全部记录数
}
5.外层方法返回给前端
exporeturnmessage<list<xxxEntity>> response = exporeturnmessage<list<xxxEntity>>();
...... //其他处理
response.setcontent(xxx, pageInfo); //最后要返回分页实体给前端,之后前端才可以显示一共有多少页
C#代码中使用的分页实体PaginationEntity,PaginationEntity pageInfo定义:
public class PaginationEntity
{
public PaginationEntity();
public bool IsTotalResult { get; set; }
public string OrderBy { get; set; }
public int PageCount { get; }
public int PageIndex { get; set; }
public int PageSize { get; set; }
public int QueryDataType { get; set; }
public int RecordCount { get; set; }
}
注意1:在程序中必须对分页实体中的pageInfo.RecordCount属性赋值,并且不能对pageInfo.PageCount赋值,因为引用的dll中都会实现对pageInfo.PageCount的赋值,这需要根据pageInfo.RecordCount / pageInfo.PageSize获取,但是却不是简单地这样写,而是要判定是整数还是分数,是分数说明还有个尾巴(不足一页的记录),需要增加一页
注意2:最后一定要注意将pageInfo返回给前端(或者WCF),如果使用expo,则形式为result.setcontent(list, pageInfo)第二部分:说明部分
说明1:oracle中的分页可以使用函数row_number()或者rownum属性两种方式,下面也是根据这两个或者这两个的组合使用的
说明2:关于rownum属性的使用,主要是不能直接使用“ rownum > 数字常量 ”的方式,只能使用小于号的方式(等于号也不能用),因为满足条件才会保留,不满足条件是会将那条记录去掉的,所以会造成一直没有满足条件的记录存在,比如使用大于号,则一直不会有满足大于号的条件存在
第三部分:示例
项目中oracle的分页写法1:很好用
select * from
(
select a.*, row_number() over (order by begindate asc) as row_num, count(*) over() as RecordCnt
from crm.vw_sys_calendarinfo a
)
where row_num > 10 and rownum <= 20 --10这个地方是需要跳过的记录数(即程序中的“( PageIndex - 1 ) * PageSize”),
--20这个地方是每页的大小(即程序中的“PageSize”)
------------------------------------------------------------------------------------------------------
oracle的分页写法2:
select * from
(
select a.*, row_number() over (order by begindate asc) as row_num, count(*) over() as RecordCnt
from crm.vw_sys_calendarinfo a
)
where row_num > 10 and row_num <= 30 --10这个地方是需要跳过的记录数(即程序中的“( PageIndex - 1 ) * PageSize”),
--30这个地方是最后一条记录标号(即程序中“PageIndex * PageSize”)
--或者使用where row_num between 11 and 30
------------------------------------------------------------------------------------------------------
oracle的分页写法3:
select * from
(
select a.*,rownum rn from --通过固化rownum为某一个变量,再通过变量可以设置大于某个常量值(不设置为另外一个变量是不行的,因为rownum属性不可以直接使用大于号或者等于号,只能使用小于号)
(
select b.* from crm.vw_sys_calendarinfo b order by begindate --可以为更为复杂的子查询
) a
where rownum <= 30 --先在记录中选出30条记录,然后在外层将rownum固化的那个变量大于10(这样就找出了中间的30-10条记录)
)
where rn > 10 --10这个地方是需要跳过的记录数(即程序中的“( PageIndex - 1 ) * PageSize”),
--30这个地方是最后一条记录标号(即程序中“PageIndex * PageSize”)
------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
--使用分页思想:分组按照行号取数据一般用法
select * from (
select row_number() over (partition by infotype order by begindate) as RowNumber, --行号 --注意,如果有partition则按照其之后的字段分组,进行组内排序,组与组之间没有任何关系
a.*, --内容
count(1) over() as RecordCnt --总行数
from crm.vw_sys_calendarinfo a
)
-----------------------------------------------------------------------------------------------------