总结一下:分页的几种办法

2023-05-16

总结一下:分页的几种办法

以mysql为例,做分页的方法,目前我总结了3种。

第一种分页:采用Query类和PageUtils类做出分页,sql用limit获取条数

第一步:Query 类的作用是对传入的分页参数做处理,并计算出当前页的起始和结束条数

@Data
public class Query extends LinkedHashMap<String, Object> {
	private static final long serialVersionUID = 1L;
	//当前页码
    private int page;
    //每页条数
    private int limit;
    public Query(Map<String, Object> params){
        this.putAll(params);
        //分页参数
        this.page = Integer.parseInt(params.get("page").toString());
        this.limit = Integer.parseInt(params.get("limit").toString());
        this.put("offset", (page - 1) * limit);
        this.put("page", page);
        this.put("limit", limit);
    }
}

第二步:根据查询的结果计算总页数

@Data
public class PageUtils implements Serializable {
	private static final long serialVersionUID = 1L;
	//总记录数
	private int totalCount;
	//每页记录数
	private int pageSize;
	//总页数
	private int totalPage;
	//当前页数
	private int currPage;
	//列表数据
	private List<?> list;
	
	/**
	 * 分页
	 * @param list        列表数据
	 * @param totalCount  总记录数
	 * @param pageSize    每页记录数
	 * @param currPage    当前页数
	 */
	public PageUtils(List<?> list, int totalCount, int pageSize, int currPage) {
		this.list = list;
		this.totalCount = totalCount;
		this.pageSize = pageSize;
		this.currPage = currPage;
		this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
	}
}

第三步: java代码中使用分页

		//对传入分页的start、limit作处理,计算出要查看也页的起始结束条数分别是多少
 		Query query = new Query(params);
 		//去数据库查询,带上计算好的分页数据(即limit所需参数)
        List<Bug> list = bugService.queryList(query);
        //查询总条数
        int total = bugService.queryTotal(query);
        //根据总条数、当前页、等数据调用PageUtils 计算出总页数
        PageUtils pageUtil = new PageUtils(list, total, query.getLimit(), query.getPage());
        return R.ok().put("page", pageUtil).put("total", total);

查询sql的写法:

 <if test="offset != null and limit != null">
            limit #{offset}, #{limit}
        </if>

这个方法简单明了,接近原生,更好理解原理,缺点是代码多,要单独查总记录数

第二种分页:采用插件pagehelper(前面博客有讲,这里简单过一下)

第一步:导包

 <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.5</version>
        </dependency>

第二步:配置yml

pagehelper:
   #指定数据库	可以不配置,插件会自动检测数据库的类型
  helper-dialect: mysql
  #分页合理化参数,默认值为false,当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
  reasonable: true
  #分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页
  support-methods-arguments: true
  #用于从对象中根据属性名取值	可以配置pageNum,pageSize,count,pageSizeZero,reasonable。不配置映射的用默认值。
  params: count=countSql

第三步:分页(只列出关键代码)

 		int start = Integer.parseInt(String.valueOf(map.get("start")));
        int limit = Integer.parseInt(String.valueOf(map.get("limit")));
        PageHelper.startPage(start,limit);
        PageInfo<HonorEntity> pageInfo = new PageInfo<>(pageHelperServiceImpl.pageHonor());

这样查出来的代码分页的参数齐全的。
不需要单独查总数,简单易用。
注意:
使用spring boot2整合 pagehelper-spring-boot-starter必须排除一下依赖
因为pagehelper-spring-boot-starter也已经在pom依赖了mybatis与mybatis-spring
所以会与mybatis-plus-boot-starter中的mybatis与mybatis-spring发生冲突

 <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <version>${pagehelper.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

深坑再现: 最近遇到使用pageHelper总数不正确的问题,总是随前端传的分页参数变化而变化。原因是:
PageInfo<HonorEntity> pageInfo = new PageInfo<>(pageHelperServiceImpl.pageHonor());pageInfo
中的数据又做了流式数据处理导致获取到的list的size.(比如这里的a就是真实去数据库查询的list集合)
参看pageHelper的底层:PageSerializable类的构造
public PageSerializable(List list) {
this.list = list;
if (list instanceof Page) {
this.total = ((Page)list).getTotal();
} else {
this.total = (long)list.size();
}
}
即:本来pageInfo 是Page类型,里面封装了total,如果做了其他处理就成了List类型即,total
获取到的是list的大小了。

第三种:mybatis-plus自带的分页

在项目使用mybatis-plus时使用它自己的分页即可。
第一步:导入mybatis-plus的包(以后项目尽量都导它,因为它和mybatis兼容的,用不用都可以)

<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.1.2</version>
		</dependency>

第二步:写一个关于分页的配置类(只有中间那个paginationInterceptor是关于分页的,这里是官网写法,最简单就是直接返回对象,其他都不用配置)

@Configuration
@EnableTransactionManagement
public class MybatisPlusConfig {
    /**
     * 注册乐观锁
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
    /**
    *分页配置
    **/
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
    /**
     * SQL执行效率插件
     */
    @Bean
    @Profile({"dev","test"})// 设置 dev test 环境开启
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        //mysql执行的最大时间,如果超过1毫秒则不执行,并抛出异常
        performanceInterceptor.setMaxTime(1000);
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }
}

第三步:代码中的使用(这里是在实现类调用dao层的方法)

 public R pageNationQuery(int start,int limit) {
        IPage<LiaochaoUser> page = new Page<>(start,limit);
       page =  liaochaoUserMapper.selectPage(page, null);
        return R.ok("查询成功").put("data",page);
    }

总结:
三种方法都可以,都不错,第一种虽然代码多但是它轻量啊,群智曾使用。
第二种,方便简单,当初傻傻找查总记录数是哪个sql,始终找不到,联通曾使用。
第三种是以后的趋势,是mybatis-plus的附属功能,网络态势项目使用。

高效查询是否存在和高效分页

1、查询是否存在还在用count(*)吗? out了!

count(0):将返回表格中所有存在的行的总数包括值为null的行 count(1):会统计包括null值的所有符合条件的字段的条数。
count(0)count(1) count(*) 都会返回null的行
count(字段):将返回表格中除去null以外的所有行的总数(有默认值的列也会被计入)
按效率排序的话,count(字段)<count(主键 id)<count(1)≈count(*)

高效查询是否存在:

SELECT 1 FROM sys_user WHERE id = 1000009 LIMIT 1

SQL不再使用count,而是改用LIMIT 1,让数据库查询时遇到一条就返回,不要再继续查找还有多少条了
业务代码中直接判断是否非空即可,存在会返回1,不存在会返回null

2、高效分页

传统分页:select * from table limit 10000,10;
偏移量越大则越慢
推荐分页:select * from table WHERE id>=23434 limit 11;

limit #{offset}, #{limit}后的两个参数是:
#{offset}起始页,它是从0开始的,第一页就是取0
#{limit}每页条数
如果只查询前几条的话,分页参数只需要一个即可
例如:select * from t_user limit 5它代表查询表中前5条

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

总结一下:分页的几种办法 的相关文章

  • C++多线程6-条件变量

    1 条件变量 std condition variable是多线程中经常用到的一个类 xff0c 它的头文件为condition variable 它常用的成员函数包括 xff0c wait notify one notify all等 它
  • Centos6.5系统升级软件操作文档

    为什么要用Centos6 5系统 xff1f 答 xff1a 因为计算板官方推荐Centos6 5 为什么要升级软件 xff1f 答 xff1a 软件需支持C 43 43 11相关库 1 系统信息 系统版本 xff1a CentOS 6 5
  • c++11多线程7-异步线程

    异步线程 异步线程的引入解决了线程有依赖关系的情景 c 43 43 11提供了std async xff0c std packaged task xff0c std promise xff0c 三种方法 1 std async std as
  • HTML中meta标签如何正确使用

    HTML中 lt meta gt 标签如何正确使用 如果我们在浏览器中按下F12或者Ctrl 43 shift 43 J xff0c 便可以打开开发者工具 xff0c 在element中即可看到 lt head gt 元素中有不少 lt m
  • 4.Linux网络编程-select和poll模型

    目录 xff1a 1 补充知识 2 简易版回射服务器的实现 3 select模型实现 4 poll模型实现 1 补充知识 span class token comment 显示进程的pid xff1a span span class tok
  • 5.Linux网络编程-select实现超时API

    一 alarm函数设置超时 它的主要功能是设置信号传送闹钟 信号SIGALRM在经过seconds指定的秒数后传送给目前的进程 xff0c 如果在定时未完成的时间内再次调用了alarm函数 xff0c 则后一次定时器设置将覆盖前面的设置 x
  • 6.Linux网络编程-epoll原理

    一 xff1a 对比select发现epoll的有点 要比较epoll相比较select高效在什么地方 xff0c 就需要比较二者做相同事情的方法 要完成对I O流的复用需要完成如下几个事情 xff1a 1 用户态怎么将文件句柄传递到内核态
  • 7.Linux网络编程-UNIX域套接字

    一 xff1a UNIX套接字 用于同一台pc上运行的进程之间通信 xff0c 它仅仅复制数据 xff0c 不执行协议处理 xff0c 不需要增加删除网络报头 xff0c 无需计算校验和 xff0c 不产生顺序号 xff0c 无需发送确认报
  • 8.Linux网络编程-System V消息队列

    一 xff1a 消息队列 消息队列是进程间通信的一种手段 xff0c 进程产生的数据块以链表的形式存储在消息队列中 xff0c 每个数据块都被认为是有一个类型 xff0c 接收者进程接收的数据块可以有不同的类型 消息队列有以下的几个限制 x
  • 9.Linux网络编程-SYSTEM V共享内存

    一 xff1a 内存映射文件 1 基本原理 mmap是一种内存映射文件的方法 xff0c 即将一个文件或者其它对象映射到进程的地址空间 xff0c 实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系 实现这样的映射关系后 xff
  • ubuntu16.04安装openstack(ocata)

    一 系统和openstack信息 Liunx系统 xff1a ubuntu16 04 server 64位 openstack版本 xff1a stable ocata 二 VMware配置 1 处理器 xff1a 数量1 xff0c 核心
  • 代码注释规范

    一 背景 1 当我们第一次接触某段代码 xff0c 但又被要求在极短的时间内有效地分析这段代码 xff0c 我们需要什么样的注释信息 xff1f 2 怎么样避免我们的注释冗长而且凌乱不堪呢 xff1f 3 在多人协同开发 维护的今天 xff
  • 1.Linux网络编程-字节序和地址转换函数

    1 IPv4套接口地址结构 IPv4套接口地址结构通常称为 网际套接字地址结构 xff0c 它以 sockaddr in 命名 xff0c 定义在头文件 lt netinet in h gt 中 struct sockaddr in uin
  • 2.Linux网络编程-socket函数和C2S实现

    1 TCP客户 服务器模型 TCP服务器 xff1a socket gt bind gt listen gt accept gt block直至客户连接到达 gt read gt 处理请求 gt write gt read gt close
  • form表单通过request取不到值multipart/form-data 文件上传表单中传 递参数无法获取的原因!

    1 什么是multipart form data 首先我们需要明白在html中的enctype属性 xff0c enctype xff1a 规定了form表单在发送到服务器时候编码方式 他有如下的三个值 application x www
  • 3.Linux网络编程-粘包处理

    visiopacket h Created on 2019年5月8日 Author hfeng liu 粘包处理 xff1a 由于TCP是基于流传输的机制 xff0c 当发送多个间隔较小的小报文时 xff0c 它会在缓冲区中缓存成一个报文发
  • linux shell脚本执行sql语句建表建库

    linux shell脚本执行sql语句建表建库 1 创建sql脚本2 创建shll脚本 1 创建sql脚本 创建contract ddl sql span class token comment 创建数据库contract user sp
  • 【Windows版】VScode配置C++开发环境

    博客已更新 xff1a Windows版 VScode配置C 43 43 开发环境 花花少年的博客 CSDN博客
  • Windows+COLMAP三维重建教程【exe安装】

    一 步骤 1 下载COLMAP COLMAP COLMAP 2 解压并运行COLMAP 3 稀疏三维重建 xff0c 生成稀疏图 4 稠密图三维重建 xff0c 生成稠密图 二 可能出现的问题 1 Dense stereo reconstr
  • FFmpeg教程(超级详细版)

    一 参考资料 通过ffmpeg把图片转换成视频 FFmpeg命令 一 使用filter complex命令拼接视频 FFmpeg 视频处理入门教程给新手的 20 多个 FFmpeg 命令示例 FFmpeg命令行转码 ffmpeg 翻译文档

随机推荐

  • yolov5+Deepsort实现目标跟踪

    一 参考资料 项目源码 pytorch yolo5 43 Deepsort实现目标检测和跟踪 工程落地 YoloV5 43 deepsort 43 Fast ReID 完整行人重识别系统 xff08 三 xff09 yolov5 deeps
  • 华为Ascend昇腾适配PyTorch框架

    一 参考资料 PyTorch用户文档 PyTorch网络模型移植 amp 训练指南 AscendPyTorch 第三方框架适配 二 重要说明 CPU架构为ARM架构时 xff0c 由于社区未提供ARM架构CPU版本的torch包 xff0c
  • 提高工作效率的宝藏网站和宝藏工具

    一 好用的网站 面包多 面包多 创作者在面包多 xff0c 通过出售课程 xff0c 文章 xff0c 绘画 xff0c 创意作品 xff0c 软件 xff0c 电子书 xff0c 音乐 xff0c 游戏 xff0c 咨询服务 xff0c
  • ubuntu服务器相关教程

    二 常用操作 1 ssh相关 span class token comment 安装ssh服务 span span class token function sudo span span class token function apt g
  • 超级实用的C++学习网站

    重要说明 xff1a 该博客长期更新 xff0c 方便读者查阅 xff01 一 参考资料 学习C 43 43 这几个网站足矣 二 C 43 43 学习网站 C 43 43 中文网 cppreference 当之无愧的C 43 43 学习第一
  • Vue 安装 Element Plus

    Element UI 是一款基于 Vue 的桌面端组件库 xff0c 提供了丰富的PC端组件 xff0c 简化了常用组件的封装 xff0c 大大降低了开发难度 随着 Vue 版本的更新 xff0c Element UI 2 x 升级到了El
  • gpio接口编程实例

    一 GPIO gpio general purpose ports 通用输入 输出端口 gpio的操作是所有硬件操作的基础 xff0c 这是底层开发人员必须掌握的 以三星公司的s3c2410 s3c2440为例做一下简要说明 s3c2410
  • ubuntu设置pycharm的桌面快捷方式

    写在最前面 xff1a 感谢大佬的分享 xff0c 参考了原文之后操作了一番 xff0c 除了pycharm xff0c 其他类似的软件也是一样的步骤即可创建桌面快捷方式 附上原文链接 xff1a Ubuntu 下安装pycharm 以及创
  • Anaconda在Ubuntu下的安装与简单使用

    一 Anaconda的安装 参考博客 ubuntu16 04下安装 amp 配置anaconda 43 tensorflow新手教程 1 下载 Miniconda 2 安装Miniconda bash Miniconda3 py39 4 1
  • 目标检测中NMS(非极大抑制)的概念理解

    参考博客 物体检测中常用的几个概念迁移学习 IOU NMS理解 目标定位和检测系列 xff08 3 xff09 xff1a 交并比 xff08 IOU xff09 和非极大值抑制 xff08 NMS xff09 的python实现 一 NM
  • VMware虚拟机上不能使用CUDA/CUDNN

    参考博客 VMware虚拟机上不能使用CUDA Linux Ubuntu 系统查看显卡型号 一 综述 虚拟机的显卡是虚拟的 xff0c 不能使用CUDA 虚拟机上装Nvidia显卡驱动会导致其他驱动全都不能用 xff0c 所以不能在虚拟机上
  • CUDA、CUDNN在windows下的安装及配置

    参考文章 全网最详细 Windows 安装 TensorFlow2 0 GPU 详细教程 Wind10安装anaonda 43 cuda10 1 43 cudnn 43 pytorch 43 tensorflow gpu win10 43
  • windows下CUDA的卸载以及安装

    参考博客 windows 7 下cuda 9 0 卸载 cuda8 0 安装 一 前言 对于一个刚玩CUDA菜鸟来说 xff0c 安装问题就是一个巨大的坑 xff0c 安装过程里面有很多需要注意的细节 xff0c 很多自定义的选项 xff0
  • 宇宙最强VisualStudio2017配置pyQt5用于python3.6的UI界面工具

    前言 请务必注意我的写作日期是2017年12月10日 现在的新版都在不停的变化中 xff0c 希望会越来愈好 2017年3月18日 xff0c 微软发布了Visual Studio2017 xff0c 其中的社区版可以自由下载并应用 xff
  • 【CVPR2019】超分辨率文章,SRFBN: Feedback Network for Image Super-Resoluition

    论文地址 代码 CVPR的单图像超分辨率文章 xff0c 主要是用回传机制来提高超分辨率的效果 xff0c 且不引入过多的参数 主要是设计了一个feedback模块 xff0c 多次回传 xff0c 如下图所示 xff1a 上一次feedb
  • selenium与browsermob-proxy

    BrowserMob Proxy允许您操作HTTP请求和响应 xff0c 捕获HTTP内容 xff0c 并将性能数据导出为HAR文件 BMP作为独立的代理服务器运行良好 xff0c 嵌入Selenium测试时尤其有用 下载地址如下 http
  • Ubuntu下Samba服务器搭建

    看网上Samba的搭建教程比较乱 xff0c 因此自己将Samba的搭建过程记录下来 xff0c 方便需要用到时还可以查看 1 安装 Samba xff1a apt get install samba 2 创建一个用于分享的 Samba 目
  • linux 第一章 shell编程及自动化运维实现

    linux shell编程及自动化运维实现 第一章 变量 一 shell 前言 1 shell语言的特点 SHELL语言是指Unix操作系统的命令语言 xff0c 同时又是该命令语言的解释程序的简称 shell本身是一个用c语言编写的程序
  • Error running 'ApplicationRun': 'xxx\jdk1.8.0_191\jre' is not a valid JRE home

    Error running ApplicationRun xxx jdk1 8 0 191 jre is not a valid JRE home解决办法 春节刚过 xff0c 疫情肆虐 从没见过如此冷清的成都 xff0c 阴沉的天空 xf
  • 总结一下:分页的几种办法

    总结一下 xff1a 分页的几种办法 以mysql为例 xff0c 做分页的方法 xff0c 目前我总结了3种 第一种分页 xff1a 采用Query类和PageUtils类做出分页 xff0c sql用limit获取条数 第一步 xff1