使用传入的总记录数实现一条sql语句完成分页查询
使用传入的总记录数实现一条sql语句完成分页查询
问题:在传统的分页查询的实现中不可避免的需要两条sql语句,一条用于查询数据一条用于查询总记录数。如下面的实际代码所示:
Img1
当然如果使用存储过程的话是可以渐少一次数据库来回的,但是它依然是两条sql语句,一条查数据一条查总记录数。但我们在架构层面拒绝使用存储过程,因为它将逻辑分散在了应用程序和数据库中,不好维护,并且在SqlServer2008中也没有足够的证据证明存储过程更高效。
很多人的直觉认为查询总记录数的那行没有必要,但是直觉只是第一步,项目中需要的是解决方案。
解决方案:
从客户端输入总记录数,从而避免一次对总记录数的查询。首先将分页查询的参数封装为一个简单对象PagingInput,它属于模型分类中的输入模型类别所以以Input作为命令的后缀,其类图如下:
Img2
pagingInput的代码
namespace jDTS {
/// <summary>
/// 分页输入参数
/// </summary>
public class PagingInput {
/// <summary>
/// 构造分页参数
/// </summary>
/// <param name="pageIndex">页索引</param>
/// <param name="pageSize">页尺寸</param>
/// <param name="sortField">排序字段</param>
/// <param name="sortOrder">排序方向</param>
public PagingInput(int pageIndex, int pageSize, string sortField, string sortOrder) {
this.pageIndex = pageIndex;
this.pageSize = pageSize;
this.sortField = sortField;
this.sortOrder = sortOrder;
}
/// <summary>
/// 构造分页参数
/// </summary>
/// <param name="pageIndex">页索引</param>
/// <param name="pageSize">页尺寸</param>
/// <param name="sortField">排序字段</param>
/// <param name="sortOrder">排序方向</param>
/// <param name="total">总记录数</param>
public PagingInput(int pageIndex, int pageSize, string sortField, string sortOrder, int? total)
: this(pageIndex, pageSize, sortField, sortOrder) {
this.total = total;
}
/// <summary>
/// 页索引。零基索引,即第一页对应0
/// </summary>
public int pageIndex { get; set; }
/// <summary>
/// 页尺寸
/// </summary>
public int pageSize { get; set; }
/// <summary>
/// 排序字段
/// </summary>
public string sortField { get; set; }
/// <summary>
/// 排序方向
/// </summary>
public string sortOrder { get; set; }
/// <summary>
/// 归档数据有一个特性,就是它的总记录数是不改变的,所以传入total以渐少一次数据库count查询
/// </summary>
public long? total { get; set; }
/// <summary>
/// 查看total字段是否为空或者0
/// </summary>
public bool IsTotalNullOrZero { get { return !total.HasValue || total.Value == 0; } }
/// <summary>
/// pageSize * pageIndex的计算值
/// </summary>
public int SkipCount { get { return pageSize * pageIndex; } }
/// <summary>
/// 判断分页输入参数是否合法
/// </summary>
/// <returns></returns>
public bool IsValid() {
if (string.IsNullOrEmpty(sortField) || string.IsNullOrEmpty(sortOrder)) {
throw new jDTSException("排序是必须的");
}
if (sortOrder != "asc" && sortOrder != "desc") {
throw new jDTSException("排序方向只能是asc或desc,小写形式");
}
return true;
}
}
}
将GetPlistNodeELementPermissionTrs的与分页有关的形参替换为PagingInput类,重构后的代码如下:
Img3
相应的表现层的代码也需要做调整,从表现层收集来自界面层输入的total参数,注意total是可空的类型(int?)所以界面层可以选择是否传入:
Img4
现在服务端代码已经实现了一个接收可空的total参数的契约,如果本模块确实要使用这个一次查询机制的话则只需在客户端传入total参数即可。像下面这样在beforload事件中附加一个total参数:这里使用的是国产的miniui框架,成熟的js表现层框架都有类似的事件
Img5
另外要记得在前台的js方法search中将total置为0,因为search不是翻页,调用search即表示查询条件有变化,查询条件变化则总记录数通常会变化,所以需将total置为0表示让服务器端进行count查询(还记得前文的PagingInput模型上有个只读的IsNullOrZero属性吗?服务器端就是根据它来判断是否要count一次数据库的)。下面是归档模块中的一个search方法,它在每次search的时候都将传向服务器端的total参数置为0:
Img6
适用场景:
适用这个解决方案的场景并不常见,因为它要求查询的总记录数是固定的或者是不频繁改变的,在我们的项目中目前发现有两个场景适用:1查询归档档案(Record),因为数据归档后它的总记录数是不变的;2查询本人的登录记录(VisitingLog),因为自己的登录次数在下次登录的时候才会改变。
当然如果界面上配上一个刷新按钮,刷新的时候将传向服务器端的total参数置为0的话,增删改记录不频繁的模块也是可以这么干的。
使用传入的总记录数实现一条sql语句完成分页查询的更多相关文章
- [MSSQL]如何高效查询表的总记录数
如何高效查询表的总记录数?[总结-整理-马克] 首先想到的自然是在表主键上应用COUNT函数来查询了,这个是目前使用最多的方法,没有之一 ) ROWS FROM product 这里再给出一些其它方法 ...
- mysql的分页存储过程,能够传出总记录数
最近用mysql + asp.net来写网站,既然mysql已经支持存储过程了,那么像分页这么常用的东西,当然要用存储过程啦 不过在网上找了一些,发现都有一个特点——就是不能传出总记录数,干脆自己研究 ...
- SQL Server 怎么在分页获取数据的同时获取到总记录数
SQL Server 获取数据的总记录数,有两种方式: 1.先分页获取数据,然后再查询一遍数据库获取到总数量 2.使用count(1) over()获取总记录数量 SELECT * FROM ( SE ...
- myBatis框架_关于怎么获得多表查询的总记录数
<!-- 查找总记录数 --> <select id="billCount" resultType="int"> select coun ...
- MSSQL语句学习(查询表的总记录数)
如何高效查询表的总记录数(通用方法) SELECT COUNT(1) ROWS FROM product 野路子1:利用系统自带的存储过程SP_SPACEUSED,详细的使用方式推荐谷哥或度娘, EX ...
- SqlServer快速获得表总记录数(大数据量)
--第1种 执行全表扫描才能获得行数 SELECT count(*) FROM BUS_tb_UserGradePrice --第2种 执行扫描全表id不为空的,获得行数 select count(u ...
- 腾讯云图片鉴黄集成到C# SQL Server 怎么在分页获取数据的同时获取到总记录数 sqlserver 操作数据表语句模板 .NET MVC后台发送post请求 百度api查询多个地址的经纬度的问题 try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会 不会被执行,什么时候被执行,在 return 前还是后? js获取某个日期
腾讯云图片鉴黄集成到C# 官方文档:https://cloud.tencent.com/document/product/641/12422 请求官方API及签名的生成代码如下: public c ...
- 分页查询——Hibernate Criteria实现一次查询取得总记录数和分页后结果集
使用Hibernate criteria进行分页查询时,如何实现一次查询取得总记录数和分页后结果集 - bto310 - ITeye博客 https://bto310.iteye.com/blog/1 ...
- MYSQL使用group by,如何查询出总记录数
比如有这样一条SQL,根据t.user_id,t.report_date两个字段统计 这样前端页面能展示数据,但往往需要一个总记录数,在有分页的情况下用到 一种解决方法是在外面套一层,然后对其coun ...
随机推荐
- 【百度地图API】如何使用suggestion--下拉列表方式的搜索建议
原文:[百度地图API]如何使用suggestion--下拉列表方式的搜索建议 摘要: 百度地图上有一个很强大的搜索建议功能,以下拉列表的方式展示出来.比如,输入“百度”,下拉列表中就会出现“北京市海 ...
- 微信公众平台接口,asp.net实现
原文:微信公众平台接口,asp.net实现 我为自己的笑话网开发了一个微信公众平台的接口,在这里分享给大家,希望能对朋友们有帮助,如果有什么地方写的不好,好请大家指点! 首先是要进行认证,认证的时候, ...
- IOS数组排序等
一.UITextField的代理方法 #pragma mark 当文本框开始编辑的时候调用---开始聚焦 - (void)textFieldDidBeginEditing:(UITextField * ...
- 加载xib文件的两种方式
一.加载xib文件的两种方式 1.方法一(NewsCell是xib文件的名称) NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@&quo ...
- 《自己动手写CPU》写书评获赠书活动结果
<自己动手写CPU>写书评获赠图书的读者有: 京东:8***2.16号哨兵.magicyu.kk6803.jddickyd.杰出的胡兵 亚马逊:徐贺.马先童.jaychen.farmfar ...
- Serialization performance analysis
Serialization performance analysis http://www.skyscanner.net/blogs/serialization-performance-analysi ...
- PhotoShop CC安装抠图插件KnockOut 2
1.KnockOut 2只有32位版本,因此需要给32位的PhotoShop CC安装. 2.下载地址:http://www.cr173.com/soft/28207.html 3.安装KnockOu ...
- Java 之Integer相等比较
1.问题提出 今天在和同事讨论问题的时候,无意间谈到了Integer对象的比较,先看下代码: package test; public class IntegerEqual { /** * @para ...
- JavaScript 多级联动浮动(下拉)菜单 (第二版)
JavaScript 多级联动浮动(下拉)菜单 (第二版) 上一个版本(第一版请看这里)基本实现了多级联动和浮动菜单的功能,但效果不是太好,使用麻烦还有些bug,实用性不高.这次除了修改已发现的问 ...
- .NET的微型Web框架 Nancy
.NET的微型Web框架 Nancy .NET的微型Web框架 Nancy 大部分微软平台的开发人员如果选择开发框架只能是在ASP.NET WEBFORM和ASP.NET MVC两个之间选择. 而 ...