DoytoQuery中的分页排序方案示例详解

目录
  • 引言
  • 分页
    • 分页接口
  • 排序
  • 请求对象
  • 响应对象
  • 小结

引言

分页和排序是数据库提供的两项基本的查询功能。

以MySQL为例,一条典型的SQL查询语句如下:

SELECT * FROM t_user
ORDER BY create_time DESC, username ASC
LIMIT 10 OFFSET 20

那么在前后端交互中,前端应该如何向后端传递分页和排序有关的信息呢?需要传递哪些参数?参数的意义和格式又是什么?

分页

分页的语句为LIMIT 10 OFFSET 20,其中10为每页的大小,20为查询的偏移量,也就是查询表中的第21到30条共计10条数据。

但是在设计接口时,通常不会要求前端直接传入OFFSET参数,而是通过传入页号和分页大小,来计算出OFFSET的值。

在这个例子中,假设前端的页号从1开始,那么需要查询的数据就是分页大小为10的第3页数据,对应的OFFSET的值的计算式为(3-1)*10 = 20

前端在调用后端查询接口时,通常会传入页号和每页大小,由后端计算出OFFSET用于分页查询。这里页号的参数名称定义为pageNumber,分页大小的参数名定义为pageSize, 则以起始页号为1为例,OFFSET的计算公式为:

(pageNumber - 1) * pageSize

而前端的传值应为

?pageNumber=3&pageSize=10

分页接口

不同的数据库的分页语句并不一致,但是一般都需要三个参数:SQL语句,分页大小,偏移量,所以定义一个构建分页语句的接口Dialect,根据访问的数据库提供对应的分页实现。

public interface Dialect {
    String buildPageSql(String sql, int limit, long offset);
}

排序

排序的语句为ORDER BY create_time DESC, username ASC, 其中ORDER BY为SQL的关键字,可以将其定义为参数名。因为是用于排序,所以我将其取名为sort,对应的值为create_time DESC, username ASC。因为前端GET请求需要对参数值里的空格进行转义,为避免这个问题,将值里的,转为;,将DESC/ASC前的空格转为,,最终前端传值如下:

?sort=create_time,desc;username,asc

请求对象

综合以上分页和排序的参数定义和说明,前端的传值如下:

?pageNumber=3&pageSize=10&sort=create_time,desc;username,asc

那么后端就可以定义如下PageQuery类用于分页和排序参数的处理:

public class PageQuery {
    private Integer pageNumber;
    private Integer pageSize;
    private String sort;
}

每条查询都有进行显示或隐式的分页和排序,比如:

SELECT * FROM t_user

SELECT * FROM t_user
ORDER BY id ASC
LIMIT ∞ OFFSET 0

等价

所以PageQuery应当作为所有查询对象的父类,以便为数据查询提供分页和排序的能力。

响应对象

对于前端的分页查询请求,除了返回对应的数据列表外,还需要返回总的数据条数total以帮助前端计算总页数,计算公式为⌈total/size⌉。对应的响应对象定义如下:

public class PageList<T> {
    private final List<T> list;
    private final long total;
}

小结

本篇主要介绍了DoytoQuery中对于数据库查询中分页和排序功能的一种面向对象的解决方案,就这。更多关于DoytoQuery分页排序的资料请关注我们其它相关文章!

(0)

相关推荐

  • DoytoQuery中关于N+1查询问题解决方案详解

    目录 1. 背景 2. SQL层的解决方案 3. ORM应用层的解决方案 4. 小结 1. 背景 Java Persistence with Hibernate 在12.2.1小节使用如下例子描述 n+1查询问题: List<Item> items = em.createQuery("select i from Item i").getResultList(); // select * from ITEM for (Item item : items) { assertTr

  • DoytoQuery中的查询映射方案详解

    目录 引言 四种字段映射方式详解 1. 后缀映射 2. OR映射 3. 嵌套查询映射 4. 直接映射 总结 附录I: 后缀支持列表 引言 DoytoQuery作为一个ORM框架,在研发过程中积累了很多全新的思路和解决方案,其中一个核心方案就是将查询对象的字段映射为SQL语句中的WHERE条件进行动态查询,目前支持四种字段映射方式. 让我们看看如何为以下UserEntity编写查询对象: @Getter @Setter @Entity public class UserEntity extends

  • MybatisPlus实现对象嵌套关联查询一对多List集合查询

    目录 对象嵌套关联查询一对多List集合查询 mybatis嵌套关联查询如下 一对多查询(经典案例) 条件 数据库 代码实现 对象嵌套关联查询一对多List集合查询 mybatis嵌套关联查询如下 由于我的是一对集合查询,所以我有两个类. @Data @TableName("tb_user") public class User {     @TableId(type= IdType.INPUT)     private String id;     @TableField("

  • DoytoQuery 聚合查询方案示例详解

    目录 1. 引言 2. 聚合查询映射 2.1. 前缀映射 2.2. 分组聚合 2.3. HAVING 2.4. 动态查询 2.5. 查询接口定义 3. 完整示例 4. 总结 1. 引言 聚合查询是数据库提供的另一种常用的用于数据的统计和计算的查询功能,它通过提供一系列聚合函数来汇总来自多个行的信息. DoytoQuery采用字段前缀映射的方式来将字段名映射为聚合函数,再配合@GroupBy注解,Having接口以及Query对象,完成整条聚合查询语句的映射. 2. 聚合查询映射 2.1. 前缀映

  • MySQL详细讲解多表关联查询

    目录 数据库设计范式 外键 内连接 外连接 结语 数据库设计范式 目前数据库设计有五种范式 , 一般我们数据库只需要满足前三项即可 第一范式 : 确保每列保持原子性 什么是原子性? 意思就是不可再分的,例如下 联系方式有 QQ,微信 , 电话等等 , 显然此列不满足原子性, 如果是单独的QQ或者电话等,则只有一个, 满足第一范式 第二范式 : 要有主键,要求其他字段都依赖于主键 为什么主键这么重要? 我们可以这样理解, 如果把表当作一个队伍, 那么主键就是这个队伍的队旗 • 没有主键就没有唯一性

  • DoytoQuery中的分页排序方案示例详解

    目录 引言 分页 分页接口 排序 请求对象 响应对象 小结 引言 分页和排序是数据库提供的两项基本的查询功能. 以MySQL为例,一条典型的SQL查询语句如下: SELECT * FROM t_user ORDER BY create_time DESC, username ASC LIMIT 10 OFFSET 20 那么在前后端交互中,前端应该如何向后端传递分页和排序有关的信息呢?需要传递哪些参数?参数的意义和格式又是什么? 分页 分页的语句为LIMIT 10 OFFSET 20,其中10为

  • Java使用Collections.sort()排序的示例详解

    Java中Collections.sort()排序详解,通过实例代码给大家讲解,具体代码如下所示: public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("beijing"); list.add("shanghai"); list.add("hangzhou"); Collections.

  • React Native 中实现确认码组件示例详解

    目录 正文 实现原理 开源方案 正文 确认码控件也是一个较为常见的组件了,乍一看,貌似较难实现,但实则主要是障眼法. 实现原理 上图 CodeInput 组件的 UI 结构如下: <View style={[styles.container]}> <TextInput autoFocus={true} /> <View style={[styles.cover, StyleSheet.absoluteFillObject]} pointerEvents="none&

  • Go语言中的字符串处理方法示例详解

    1 概述 字符串,string,一串固定长度的字符连接起来的字符集合.Go语言的字符串是使用UTF-8编码的.UTF-8是Unicode的实现方式之一. Go语言原生支持字符串.使用双引号("")或反引号(``)定义. 双引号:"", 用于单行字符串. 反引号:``,用于定义多行字符串,内部会原样解析. 示例: // 单行 "心有猛虎,细嗅蔷薇" // 多行 ` 大风歌 大风起兮云飞扬. 威加海内兮归故乡. 安得猛士兮守四方! ` 字符串支持转义

  • C++中#include头文件的示例详解

    fstream是C++ STL中对文件操作的合集,包含了常用的所有文件操作.在C++中,所有的文件操作,都是以流(stream)的方式进行的,fstream也就是文件流file stream. 最常用的两种操作为: 1.插入器(<<) 向流输出数据.比如说打开了一个文件流fout,那么调用fout<<"Write to file"<<endl;就表示把字符串"Write to file"写入文件并换行. 2.析取器(>>

  • Python中bisect的用法及示例详解

    bisect是python内置模块,用于有序序列的插入和查找. 查找: bisect(array, item) 插入: insort(array,item) 查找 import bisect a = [1,4,6,8,12,15,20] position = bisect.bisect(a,13) print(position) # 用可变序列内置的insert方法插入 a.insert(position,13) print(a) 输出: 5 [1, 4, 6, 8, 12, 13, 15, 2

  • C/C++语言八大排序算法之桶排序全过程示例详解

    基本思路是将所有数的个位十位百位一直到最大数的最高位一步步装桶,先个位装桶然后出桶,直到最高位入桶出桶完毕. 首先我们要求出一个数组的最大数然后求出他的最大位数 //求最大位数的函数 int getmaxweisu(int* a,int len)// { int max = a[0]; for (int i = 0; i < len; i++) { if (max < a[i]) { max = a[i]; } } int count = 1; while (max/10) { count++

  • Python中三种花式打印的示例详解

    目录 1. 引言 2. 打印圣诞树 2.1 问题描述 2.2 问题分析 3. 打印字母版圣诞树 3.1 问题描述 3.2 问题分析 4. 打印字母版菱形 4.1 问题描述 4.2 问题分析 5. 总结 1. 引言 在Python中有很多好玩的花式打印,对厉害的高手来说可能是小菜一碟,对入门的小白来说往往让人望而退步,我们今天就来挑战下面三个常见的花式打印吧... 2. 打印圣诞树 2.1 问题描述 编码实现函数christmas_tree(height),该函数输入参数为一个整数表示圣诞树的高度

  • 详解Python中生成随机数据的示例详解

    目录 随机性有多随机 加密安全性 PRNG random 模块 数组 numpy.random 相关数据的生成 random模块与NumPy对照表 CSPRNG 尽可能随机 os.urandom() secrets 最佳保存方式 UUID 工程随机性的比较 在日常工作编程中存在着各种随机事件,同样在编程中生成随机数字的时候也是一样,随机有多随机呢?在涉及信息安全的情况下,它是最重要的问题之一.每当在 Python 中生成随机数据.字符串或数字时,最好至少大致了解这些数据是如何生成的. 用于在 P

  • Go语言中循环语句使用的示例详解

    目录 一.概述 1. 循环控制语句 2. 无限循环 二.Go 语言 for 循环 1. 语法 2. for语句执行过程 3. 示例 4. For-each range 循环 三.循环嵌套 1. 语法 2. 示例 四.break 语句 1. 语法 2. 示例 五. continue 语句 1. 语法 2. 示例 六.goto 语句 1. 语法 2. 示例 一.概述 在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句. 循环程序的流程图: Go 语言提供了以下几种类型循环

随机推荐