使用传入的总记录数实现一条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的话,增删改记录不频繁的模块也是可以这么干的。

 
 
分类: ASP.NET MVC

使用传入的总记录数实现一条sql语句完成分页查询的更多相关文章

  1. [MSSQL]如何高效查询表的总记录数

    如何高效查询表的总记录数?[总结-整理-马克] 首先想到的自然是在表主键上应用COUNT函数来查询了,这个是目前使用最多的方法,没有之一 ) ROWS FROM product 这里再给出一些其它方法 ...

  2. mysql的分页存储过程,能够传出总记录数

    最近用mysql + asp.net来写网站,既然mysql已经支持存储过程了,那么像分页这么常用的东西,当然要用存储过程啦 不过在网上找了一些,发现都有一个特点——就是不能传出总记录数,干脆自己研究 ...

  3. SQL Server 怎么在分页获取数据的同时获取到总记录数

    SQL Server 获取数据的总记录数,有两种方式: 1.先分页获取数据,然后再查询一遍数据库获取到总数量 2.使用count(1) over()获取总记录数量 SELECT * FROM ( SE ...

  4. myBatis框架_关于怎么获得多表查询的总记录数

    <!-- 查找总记录数 --> <select id="billCount" resultType="int"> select coun ...

  5. MSSQL语句学习(查询表的总记录数)

    如何高效查询表的总记录数(通用方法) SELECT COUNT(1) ROWS FROM product 野路子1:利用系统自带的存储过程SP_SPACEUSED,详细的使用方式推荐谷哥或度娘, EX ...

  6. SqlServer快速获得表总记录数(大数据量)

    --第1种 执行全表扫描才能获得行数 SELECT count(*) FROM BUS_tb_UserGradePrice --第2种 执行扫描全表id不为空的,获得行数 select count(u ...

  7. 腾讯云图片鉴黄集成到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 ...

  8. 分页查询——Hibernate Criteria实现一次查询取得总记录数和分页后结果集

    使用Hibernate criteria进行分页查询时,如何实现一次查询取得总记录数和分页后结果集 - bto310 - ITeye博客 https://bto310.iteye.com/blog/1 ...

  9. MYSQL使用group by,如何查询出总记录数

    比如有这样一条SQL,根据t.user_id,t.report_date两个字段统计 这样前端页面能展示数据,但往往需要一个总记录数,在有分页的情况下用到 一种解决方法是在外面套一层,然后对其coun ...

随机推荐

  1. JavaScript Date对象介绍

    原文:JavaScript Date对象介绍 Date 日期和时间对象 1. 介绍 Date对象,是操作日期和时间的对象.Date对象对日期和时间的操作只能通过方法. 2. 构造函数 2.1 new ...

  2. HDU5014Number Sequence(贪心)

    HDU5014Number Sequence(贪心) 题目链接 题目大意: 给出n,然后给出一个数字串,长度为n + 1, 范围在[0, n - 1].然后要求你找出另外一个序列B,满足上述的要求,而 ...

  3. Cocos2d-x3.0之路--02(引擎文件夹分析和一些细节)

    关于怎么搭建好开发环境的我就不写了,网上非常多. 那么 我们来看看 引擎文件的文件夹 所谓知己知彼 百战不殆嘛 先说一下setup.py 这个文件是有关配置的python文件,比方我们在进行andro ...

  4. CocoaPods在使用中的几个问题

    来源: http://blog.cocoapods.org/Repairing-Our-Broken-Specs-Repository/ 1. 当把CocoaPods生成的workspace移动到上层 ...

  5. CSS3制作日历

    目标是制作如下面DEMO显示的一个日历效果: HTML Markup 先来看看其结构: <div class="calendar"> <span class=&q ...

  6. UIAutomator源码分析之启动和运行

    通过上一篇<Android4.3引入的UiAutomation新框架官方简介>我们可以看到UiAutomator其实就是使用了UiAutomation这个新框架,通过调用Accessibi ...

  7. 优秀个人免费私有云OwnCloud 8.0终于发布 - 亮眼新功能初探简介

    OwnCloud是一个基于Linux的私有云开源项目,用户可以免费使用它来搭建自己的私有云来进行文件和多媒体等的分享. 本人有幸在大概一年多前因为项目需要而接触和使用到OwnCloud,但不幸的是当时 ...

  8. 【Android平台安全方案】の #00-请不要在外部存储(SD卡)加密存储的敏感信息

    本文翻译自https://www.securecoding.cert.org/confluence/display/java/DRD00-J.+Do+not+store+sensitive+infor ...

  9. Java程序员应该知道的10个Eclipse调试技巧

    Eclipse是众多Java程序员实用的开发工具,其中开发技巧也是繁多,但作为优秀的Java程序员,需要掌握最起码的调试技巧. 1 条件断点 2 异常断点 3 监视点 4 评估/检查 5 修改变量值 ...

  10. leetcode第七题--Reverse Integer

    Problem: Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 ...