使用传入的总记录数实现一条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 ...
随机推荐
- 勾选Create git respository的作用
在Xcode中创建项目时会弹出Source Control选项,勾选Create git repository选项可以帮助我们对照以前项目中代码中修改的部分,为开发提供方便. 在项目完成到一定程度时, ...
- Kaggle入门——使用scikit-learn解决DigitRecognition问题
Kaggle入门--使用scikit-learn解决DigitRecognition问题 @author: wepon @blog: http://blog.csdn.net/u012162613 1 ...
- WPF应用程序支持多国语言解决方案
原文:WPF应用程序支持多国语言解决方案 促使程序赢得更多客户的最好.最经济的方法是使之支持多国语言,而不是将潜在的客户群限制为全球近70亿人口中的一小部分.本文介绍四种实现WPF应用程序支持多国语言 ...
- JavaScript超大整数加法
原文:JavaScript超大整数加法 什么是「超大整数」? JavaScript 采用 IEEE754标准 中的浮点数算法来表示数字 Number. 我也没花时间去详细了解 IEEE754标准 ,但 ...
- installshield 32位打包和64位打包的注意事项
原文:installshield 32位打包和64位打包的注意事项 32/64位问题要把握几点:1. 明确你的产品是否需要区分32/64位2. 明确你的产品中是否有32/64位的服务注册3. 了解In ...
- 让Windows 8 / 8.1 以及 Windows Server 2012 / 2012 R2的任务管理器的性能面板,显示磁盘数据
运行[diskperf -y],关闭任务管理器,重新打开即可.
- PHP 11:函数
原文:PHP 11:函数 本文章介绍PHP的函数.如何学习呢?可以从以下几个方面考虑 函数是如何定义的?区分大小写吗? 函数的参数是如何定义的? 函数是否支持重载? 函数的返回值是如何定义的. 函数有 ...
- android App Widgets
http://developer.android.com/guide/practices/ui_guidelines/widget_design.html#design http://develope ...
- [译]Java设计模式之解释器
(文章翻译自Java Design Pattern: Interpreter) 解释器模式适用于当一些内容需要翻译的时候.下面的例子是一个非常简单的解释器实现.它将字母"a"和&q ...
- 【转】【Android应用开发详解】第01期:第三方授权认证(一)实现第三方授权登录、分享以及获取用户资料
转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9057257 由于公司项目的需要,要实现在项目中使用第三方授权登录以及分享文字 ...