Mybatis/Plus 分页查询

news/2024/9/20 13:53:41/文章来源:https://www.cnblogs.com/warmNest-llb/p/18395605

 

分页查询的原理是通过将大数据量集分割成较小的部分来返回结果,以减少一次性加载和显示的数量。

接受分页参数:在分页查询中,通常会接收两个关键的参数——当前页码(current)和每页显示的数据量(size)。这些参数决定了用户希望查看哪一部分数据。

计算偏移量:根据当前页码和每页显示数据量,计算出从数据库中哪一行数据开始获取。偏移量公式:

      start = (current - 1)* size; start 的值就是数据集中的起始位置。

执行分页查询:在SQL查询中使用 Limit 字句来限制查询返回的记录数。Limit 接受两个参数——偏移量 start 和 每页显示的记录数 size,指示数据库从偏移量处开始,返回指定数量的记录。如:

select * from table_name limit start, size;
-- 这条语句将从 start 位置开始获取,获取 size 条记录。

   还有 像 PageHelper 或 RowBounds 这样的分页工具,分页查询原理虽然与 Limit 查询类似,但过程更加简化和自动化。通过简化分页原理,自动处理分页参数并返回分页后的数据。

构建查询条件:分页查询中,通常还会结合其他条件(如筛选条件),来进一步缩小查询范围。条件可以通过 where 子句进行过滤,以满足查询要求。

返回结果:数据库执行查询后,将结果集返回给应用程序。程序将结果进行展示,用户使用时可以通过调整页码和每页记录数,查看不同的部分。

通过分页查询,系统可以有效减少内存占用和网络传输的压力,提升响应速度,特别是在数据量非常大的情况下。

 

1. 在SQL内分页

SQL 使用 Limit。可以直接单表使用,也可以多表实现。

只返回数据,不返回查询总数。    

分页查询类:

/*** 分页*/
@Data
public class PageShowDto {/** 初始页 */private Integer current;/** 数量 */private Integer size;/** 开始 */private Integer start;}

 

Service实现类:

    /*** 查询** @param pageDto  分页* @param steamDto 条件* @return 信息*/@Overridepublic List<ExerciseSchemeSteamDto> findExerciseType(ExerciseSchemeSteamDto steamDto, PageShowDto pageDto) {pageDto.setStart((pageDto.getCurrent() - 1) * pageDto.getSize());return exerciseSchemeAndSteamMapper.findExerciseSchemeSteamType(steamDto, pageDto);}
current--起始页;
size--每页条数;
pageDto.getCurrent() - 1) * pageDto.getSize()-- 如:(current 3 - 1) * size 10 为 20;此时 start 为 20;

Mappe接口:

    /** 查询 */List<ExerciseSchemeSteamDto> findExerciseSchemeSteamType(@Param("steamDto") ExerciseSchemeSteamDto steamDto, @Param("pageDto") PageShowDto pageDto);

 

XML编写SQL:

    <!-- 查询两个表   -->    <select id="findExerciseSchemeSteamType"resultType="com.control.interactive.entity.dto.ExerciseSchemeSteamDto">selectes.id,es.stage_name as stageName,es.condition_scenario as conditionScenario,es.red_team_action as redTeamAction,ess.team_id as teamId,ess.team_name as teamName,ess.action_command as actionCommand,ess.scheme_id as schemeIdfrom t_exercise_scheme esleft join t_exercise_scheme_team esson es.id = ess.scheme_id<where><if test="steamDto.stageName != null and steamDto.stageName != ''">es.stage_name like concat('%', #{steamDto.stageName}, '%')</if></where>order by es.id<if test="pageDto != null">limit #{pageDto.size} offset #{pageDto.start}</if></select>
current--起始页;
size--每页条数;
pageDto.getCurrent() - 1) * pageDto.getSize()-- 如:(current 3 - 1) * size 10 为 20;此时 start 为 20;
此时分页查询是从 第21条 数据开始截取,每页 10条 数据。

 

查询直接传递参数 current 与 size。想进一步使用条件过滤,直接传递相应的字段,如 name-模糊查询等等...

 

优化返回结果,可以使用 `com.baomidou.mybatisplus.extension.plugins.pagination.Page` 的 Page<> 返回。

 

2. 使用 PageHelper 插件

PageHelper 是 Mybatis 中常用的分页插件。再查询SQL前,自动处理分页逻辑并为查询语句添加适当的 Limit 字句。

 

注入依赖:

        <!-- PageHelper 分页插件 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>4.1.6</version></dependency>

PS:注入依赖使用 注意 与 JSqlParser 的版本冲突,根据情况进行升降 pagehelper 版本。

 

自定义分页查询类,用于前端传值:

/*** 分页*/
@Data
public class PageShowDto {/** 初始页 */private Integer current;/** 数量 */private Integer size;}

 

ServiceImpl:

初始化分页:在调用查询方法前,通过 PageHelper.startPage(current, size) 设置当前页码和每页显示的记录数。

 ~~ PageHelper.startPage(1, 10);

    /*** 查询** @param pageDto 分页* @param steamDto        条件* @return 信息*/@Overridepublic R<PageInfo<ExerciseSchemeSteamDto>> findExercise(PageShowDto pageDto, ExerciseSchemeSteamDto steamDto) {// 分页参数设置
        PageHelper.startPage(pageDto.getPageNum(), pageDto.getPageSize());List<ExerciseSchemeSteamDto> exerciseSchemeSteam = exerciseSchemeAndSteamMapper.findExerciseSchemeSteam(steamDto);PageInfo<ExerciseSchemeSteamDto> steamPageInfo = new PageInfo<>(exerciseSchemeSteam);return R.ok(steamPageInfo);}

PageHelper 拦截SQL语句,再执行SQL前自动添加 Limit 和 Offset 子句,便于在数据库表中查询所需数据。

 

XML SQL 编写:

    /** 查询 */List<ExerciseSchemeSteamDto> findExerciseSchemeSteam(@Param("steamDto") ExerciseSchemeSteamDto steamDto);

 

    <!-- 查询--><select id="findExerciseSchemeSteam"resultType="com.hrzn.control.interactive.blue.entity.dto.ExerciseSchemeSteamDto">selectes.id as id,es.stage_name as stageName,es.condition_scenario as conditionScenario,es.red_team_action as redTeamAction,ess.team_id as teamId,ess.team_name as teamName,ess.action_command as actionCommand,ess.scheme_id as schemeIdfrom t_exercise_scheme es left join t_exercise_scheme_team esson es.id = ess.scheme_id<where><if test="steamDto.stageName != null and steamDto.stageName != ''">es.stage_name like concat('%', #{steamDto.stageName}, '%')</if></where>order by es.id;</select>

后台会通过 PageHelper 将SQL 改为 select (字段) from (表名) limit 0, 10;

 

返回结果:查询完成后,优化查询返回结果可以使用 PageInfo<>,PageHelper 会将结果封装到一个 PageInfo对象,其中包含查询结果、总数据量、总页数等分页信息。

 

优点:

  简化分页代码:只需要调用 startPage() 方法,分页逻辑自动处理。

  集成度高:与 Mybatis 无缝集成,直接应用于现有的 Mybatis 查询。

 

简单使用https://www.cnblogs.com/warmNest-llb/p/18120512

 

3. 使用 RowBounds 分页

RowBounds 是 Mybatis 自带的一种分页处理方式,通过逻辑分页(在内存中分页)来控制查询结果的范围。

 

RowBounds:

 

构建查询:

    /*** 查询** @param schemeSteamPage 条件* @param pageDto 分页* @return true*/@Overridepublic List<ExerciseSchemeSteamDto> findExerciseRowBounds(ExerciseSchemeSteamDto schemeSteamPage, PageShowDto pageDto) {RowBounds rowBounds = new RowBounds((pageDto.getCurrent() - 1) * pageDto.getSize(), pageDto.getSize());return exerciseSchemeAndSteamMapper.findExerciseSchemeSteamRow(schemeSteamPage, rowBounds);}

构建 RowBounds 对象:通过 创建一个 RowBounds 对象,传入偏移量 offsert 和 每页记录数 limit;

new RowBounds((pageDto.getCurrent() - 1) * pageDto.getSize(), pageDto.getSize()) 等价于 new RowBounds(offset, size);

 offset 从哪行数据开始,size 多少条数据。

 

XML 编写 SQL:

    /** 查询 */List<ExerciseSchemeSteamDto> findExerciseSchemeSteamRow(@Param("steamDto") ExerciseSchemeSteamDto steamDto, RowBounds rowBounds);

 

    <!-- 演练查询--><select id="findExerciseSchemeSteam"resultType="com.hrzn.control.interactive.blue.entity.dto.ExerciseSchemeSteamDto">selectes.id as id,es.stage_name as stageName,es.condition_scenario as conditionScenario,es.red_team_action as redTeamAction,ess.team_id as teamId,ess.team_name as teamName,ess.action_command as actionCommand,ess.scheme_id as schemeIdfrom t_exercise_scheme es left join t_exercise_scheme_team esson es.id = ess.scheme_id<where><if test="steamDto.stageName != null and steamDto.stageName != ''">es.stage_name like concat('%', #{steamDto.stageName}, '%')</if></where>order by es.id;</select>

 

 

查询与分页:Mybatis 执行查询时,将结果集取回后,根据 RowBounds 进行内存级别的分页处理。这种方式下分页逻辑是在应用程序内存中执行的,而不是在SQL查询中添加 Limit 子句。

 

 

优点:

  无需改动原始SQL:可以直接作用于已有的 Mybatis 查询。

 

缺点:

  适合小数据集:由于是内存中处理分页逻辑,对于大数据集来说性能较差。通常不推荐在大数据集上使用 RowBounds 进行分页。

 

 

4. 总结

 直接在SQL内分页,简单粗暴。

 PageHelper 自动化处理分页查询,拦截并改写 SQL,性能高,适合大数据集,推荐在 Mybatis 中使用。

 RowBounds 则是基于内存的分页方式,简单直接,但对于大数据集性能不佳,通常只适合处理小数据集的分页。

 

 


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/792105.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CentOS 7环境部署和配置GFS2共享存储

Linux、RHCS案例说明: 在CentOS 7环境部署gfs2共享存储应用。 系统环境: [root@node201 ~]# cat /etc/centos-release CentOS Linux release 7.9.2009 (Core)系统架构: [root@node203 ~]# cat /etc/hosts 192.168.1.201 node201 192.168.1.202 node202 192.168.1.203 node20…

牛逼!Vue3.5的useTemplateRef让ref操作DOM更加丝滑

前言 vue3中想要访问DOM和子组件可以使用ref进行模版引用,但是这个ref有一些让人迷惑的地方。比如定义的ref变量到底是一个响应式数据还是DOM元素?还有template中ref属性的值明明是一个字符串,比如ref="inputEl",怎么就和script中同名的inputEl变量绑到一块了呢?…

十六年所思所感,聊聊这些年我所经历的 DevOps 系统

AI 到来之前 DevOps 领域主要的发展还是在研发流程本身的延伸上,具体到某个能力,大的发展并不多。但是,像编码、测试等强耗时的场景,都有了不少新的发展,在需求分析、设计等方面也有许多探索正在进行,未来可期。作者:子丑 前不久,我因为运动时的姿势不对,导致右腿骨折…

vue3 地图(天地图,百度地图,腾讯地图,高德地图)封装组件调用 带地图搜索功能

<template><!-- 地图 --><div class="container w"><div id="map" class="map radius-md" :style="{ width: width, height: height }"></div></div> </template> <script> import {…

【优技教育】Oracle 19c OCP 082题库(第8题)- 2024年修正版

【优技教育】Oracle 19c OCP 082题库(Q 8题)- 2024年修正版 考试科目:1Z0-082 考试题量:90 通过分数:60% 考试时间:150min 本文为(CUUG 原创)整理并解析,转发请注明出处,禁止抄袭及未经注明出处的转载。 原文地址:http://www.cuug.com.cn/ocp/082kaoshitiku/38167699730…