MyBatis中使用第三方分页插件PageHelper完成分页功能

news2024/11/18 0:46:06

文章目录

  • 一、前言
  • 二、基于插件拦截方式
    • 1、自定义插件
    • 2、使用第三方插件完成分页
      • 1、分页插件的配置
      • 2、分页插件的使用

一、前言

分页是web应用程序非常重要的一个技术。数据库中的数据可能是成千上万的,不可能把这么多的数据一次显示在浏览器上面。一般根据每行数据在页面上所占的空间每页显示若干行,比如一般20行是一个比较理想的显示状态。
在这里插入图片描述

对于MyBatis中分页的操作其实是有两种,一种是基于参数的改造, 还有一种是基于插件的拦截。

对于参数的改造,可以直接使用通过添加参数limitoffset就可以实现查询从某个位置开始的若干记录,代码实现如下所示:

  <select id="selectSomeData" parameterType="map" resultType="com.somedata">
        SELECT * FROM sometable
                 ORDER BY somecolumn
                 LIMIT #{limit} OFFSET #{offset}
    </select>

这段 SQL 语句会返回从偏移量为 offset 的位置开始的limit条结果。例如:LIMIT 30,10 表示从第 31 行开始返回10行结果。

在实际应用中,我们可以将limitoffset 抽取成两个参数,并传入到 MyBatis
这种方法在这里就不怎么介绍了,这里主要介绍的是通过基于插件拦截的方式解决分页问题

二、基于插件拦截方式

1、自定义插件

我们可以通过插件的方式来实现, 这种方式更加灵活,支持实现更为复杂的分页功能。我们需要自定义一个拦截器,实现Interceptor接口,并重写其中唯一的intercept方法,在其中对 SQL 语句进行修改,添加分页信息。具体操作如下,首先自己定义一个拦截器

下面写的全是伪代码,不能直接运行的,这里只是为了引出pagehelper

public class PageInterceptor implements Interceptor {
    /**
     * 拦截方法     *     * @param invocation     * @return     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取原始的SQL语句
        String sql = (String) invocation.getArgs()[0];
        // 查询总数并计算出总页数和当前页
        int total = count(sql);
        // 如果总数小于等于0,则直接返回空结果集
        if (total <= 0) {
            return Collections.emptyList();
        }
        // 计算出当前页的起始位置和结束位置
        int offset = getOffset(pageNo, pageSize);
        int limit = pageSize;
        // 构造含分页信息的新SQL
        String newSql = getNewSql(sql, offset, limit);
        // 将新SQL替换成原来的SQL,并继续执行原有方法
        ReflectionUtils.setFieldValue(invocation, "h.sql", newSql);
        Object result = invocation.proceed();
        // 包装成Page对象,并返回
        Page<T> pageResult = new Page<>(pageNo,pageSize,total,(List<T>)result);
        return pageResult;
    }
    /**
     * @author Jeff Fong
     * @description 合成新的sql 
     * @date 2023/5/22 14:03 
     * @param: sql
     * @param: offset
     * @param: limit
     * @return java.lang.String
     **/
    private String getNewSql(String sql, int offset, int limit) {       
        return sql + " LIMIT " + offset + "," + limit;    
    }

    /**
     * @author Jeff Fong
     * @description 获取总的条数
     * @date 2023/5/22 14:03
     * @param: sql
     * @return int
     **/
    private int count(String sql){        // code omitted
        return 1;
    }
    /**
     * @author Jeff Fong
     * @description 计算出当页的offset
     * @date 2023/5/22 14:02
     * @param: pageNo
     * @param: pageSize
     * @return int
     **/
    private int getOffset(int pageNo, int pageSize) {        
        return (pageNo - 1) * pageSize;    
    }
}

然后,我们需要在 mybatis-config.xml 配置文件中注册该拦截器:

<plugins>        
	<plugin interceptor="com.example.mybatis.PageInterceptor"/></plugins>

最后,在业务代码中就可以直接使用

 public List<User> selectUserListByPage(int startRow, int pageSize){
        RowBounds rowBounds = new RowBounds(startRow,pageSize);
        String statement = "com.example.UserMapper.selectUserList";
        return sqlSession.selectList(statement,null,rowBounds);
    }

2、使用第三方插件完成分页

这里使用的插件是PageHelper, 在https://pagehelper.github.io/docs/howtouse/有关于这个插件的介绍。

1、分页插件的配置

(1)、添加依赖

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>

(2)、配置分页插件
在MyBatis的核心配置文件中配置插件

<plugins>
<!--设置分页插件-->
    <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

一定要注意plugins分页插件在mybatis-config.xml的位置,位置如果不对的话,是会直接报错的。
在这里插入图片描述

2、分页插件的使用

在需要分页的数据之前使用PageHelper.startPage(int pageNum, int pageSize)开启分页功能

  • pageNum:当前页的页码
  • pageSize:每页显示的条数

在查询获取list集合之后,使用PageInfo pageInfo = new PageInfo<>(List list, int navigatePages)获取分页相关数据。

  • list:分页之后的数据
  • navigatePages:导航分页的页码数

看看具体的代码实现,对于mapper中的接口比较简单,这里就不一一的说明;

    /**
     * limit    index,pagesize
     * index    当前页的起始索引
     * pageSize 每页显示的条数
     * pageNum  当前页的页码
     * 当前页的起始索引 = 每页条数 * 页码 - 1
     * index = pageNum * pageSize - 1
     *
     * 通过索引获得数据
     *
     * 使用MyBatis的分页插件,实现分页功能:
     * 1。需要在查询功能之前开启分页
     * PageHelper.startPage(2, 4);
     *
     * 2。在查询功能之后获取分页相关信息
     *   PageInfo<Emp> pages = new PageInfo<>(emps, 5); 5表示导航分页的数量
     */
    @Test
    public void test02() throws IOException {
        SqlSession sqlSession = getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        System.out.println("\n查询功能前启用插件.....");
        PageHelper.startPage(2, 4);
        List<User> all = mapper.findAll();
        all.forEach(System.out::println);
        System.out.println("\n");
        PageInfo<User> pages = new PageInfo<User>(all,);
        System.out.println("-------->" + pages);
    }

实际上的所有数据
在这里插入图片描述
查询第二页的数据,应该是
在这里插入图片描述
最后来看看最终的返回的详细数据:
在这里插入图片描述
看到所需要的数据,都在pageinfo对象中
首先来提一嘴
在这里插入图片描述
这里的navigatepages是什么东西?
就是相当于前端要显示的下面导航栏的东西
在这里插入图片描述
这里的navigatepages = [1,2,3,4,5....., 11]


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年4月CSDN客服月报|解决3个重大问题和26个次要问题,采纳1个用户建议

听用户心声&#xff0c;解用户之需。hello&#xff0c;大家好&#xff0c;这里是《CSDN客诉报告》第19期&#xff0c;接下来就请大家一同回顾我们4月份解决的bug&#xff5e; 一、重大问题 1、【猿如意】ChitGPT近期老是提示“我回答不过来”的问题 反馈量&#xff1a;10 2、…

【星戈瑞】Sulfo-Cyanine7 maleimide磺化CY7标记马来酰亚胺

水溶性Cyanine7 mal是一种常用的细胞标记物&#xff0c;可以被用于细胞荧光成像等应用中。它的分子结构中含有Cyanine7和mal两部分&#xff0c;其中Cyanine7是一种红外荧光染料&#xff0c;可以发出红外光&#xff0c;而mal则是一种水溶性的化合物&#xff0c;可以使Cyanine7分…

响应式与自适应的区别

响应式与自适应的区别&#xff1a; 响应式&#xff1a;一套适配多端适配不同的屏幕设备&#xff0c;即不同的视口分辨率 自适应&#xff1a;多套页面不同视口分辨率大小显示同样的网页rem、百分比等相对单位 注意&#xff1a; 在开发中&#xff0c;项目的响应式&#xff0c;一些…

Java技术接单

今天给大家介绍一个阶段性&#xff08;周期性&#xff09;能获取一定收益的Java技术接单群&#xff0c;分享给大家&#xff01;主要对搞Java的粉丝有帮助&#xff0c;因为可以赚点小钱&#xff0c;对Java技术的要求不高&#xff01; 那些感兴趣或者想直接加技术群的我给大家讲一…

JAVA8 Stream

1 Steam流式思想概述 Stream和IO流(InputStream/OutputStream)没有任何关系&#xff0c;请暂时忘记对传统IO流的固有印象&#xff01; Stream流式思想类似于工厂车间的“生产流水线”&#xff0c;Stream流不是一种数据结构&#xff0c;不保存数据&#xff0c;而是对数据进行加…

Vue 3 第二十一章:组件九(组件高级特性-组件的混入和继承)

文章目录 1. 组件的混入2. 组件的继承总结 Vue 中的组件混入和继承功能允许我们在多个组件之间共享代码&#xff0c;从而提高代码的可重用性和可维护性。 1. 组件的混入 混入是一种将多个对象合并为一个对象的技术。在 Vue 3 中&#xff0c;我们可以使用 mixins 属性来定义混…

ThingsBoard的Actor模型

0、概述 下面是我从网上查阅资料总结下来的. 1、背景 多线程编程是每个程序员的基本功,同时也是开发中的难点,处理各种“锁”的问题是让人十分头痛的一件事。例如,设计一个转账功能,怎么保证在多线程下能正常运行?你可能会说,这个简单,在进行转账操作前,先对两个账户…

【实战项目】使用C语言和easyX,一起完成数字拼图游戏吧!快来挑战一下吧~

这款简易的拼图游戏包含了15个数字方块&#xff0c;你需要将它们按照顺序排列成1~15的数字&#xff0c;就能完成游戏。 在游戏中会记录你完成拼图所用的时间。我想强调的是&#xff0c;一个精彩的游戏并不一定需要使用图片。只要功能和手感都做得出色&#xff0c;游戏同样能够…

从0到1,深刻理解Linux权限

[Linux]深刻理解Linux权限 从0到1&#xff0c;深刻理解Linux权限Linux权限的概念Linux权限管理Linux文件访问者文件类型和访问权限文件类型访问权限 文件访问权限设置修改文件权限修改文件拥有者修改所属组 umask掩码目录权限目录权限问题粘滞位 权限总结&#xff1a; 从0到1&a…

1688商品详细信息价格SKU接口

随着新零售时代的到来&#xff0c;越来越多的企业开始关注电商平台&#xff0c;其中1688平台作为国内重要的B2B电商平台之一&#xff0c;对于企业发展、产品销售等方面有着重要的价值。在使用1688平台出售商品时&#xff0c;如何优化商品详情页、提高搜索排名、增加商品曝光度&…

PG15.3.0源码编译安装日志插件pgbadger(上)

一、开启相关日志 修改后alter一定要重启&#xff0c;才会修改 pg_ctl restart -D /usr/local/pgsql/data -l logfile按照下面的方法一个个修改。 log_destination csvlog # 可选 logging_collector on log_min_duration_statement 0 log_line_prefix %t [%p]: us…

(转载)MATLAB智能算法30个案例分析(2)——基于遗传算法和非线性规划的函数寻优算法

以下内容大部分来源于《MATLAB智能算法30个案例分析》&#xff0c;仅为学习交流所用。 1 理论基础 1.1 非线性规划 非线性规划是20世纪50年代形成的一门新兴学科。1951年库恩和塔克发表的关于最优性条件(后来称为库恩塔克条件)的论文是非线性规划诞生的标志。非线性规划研究…

聚会游戏玩什么?UMO轻松炒热气氛

UMO是一款有趣的多人益智桌游&#xff0c;考验玩家耐力和技巧的比拼&#xff01;玩家将在游戏中通过特定的规则来出牌&#xff0c;谁先出完所有牌谁就赢&#xff0c;游戏非常讲究策略和运气哦~ 当玩家手上只剩一张牌时&#xff0c;必须喊出UMO&#xff01;游戏因此得名。【数字…

自学网络安全,最应该先学的五大技能树是什么?(附学习路线图)

前言&#xff1a; 近几年网络安全事件频发&#xff0c;国家对于互联网信息安全和互联网舆情的重视程度不断提升有关&#xff0c;全球网络安全岗位缺口达500万&#xff0c;中国约100万&#xff0c;产业人才需求逐年增加&#xff0c;网络安全行业的相关岗位成为炙手可热的职业。…

COMSOL光电案列应用实操教学:

COMSOL多物理场仿真软件以高效的计算性能和杰出的多场耦合分析能力实现了精确的数值仿真&#xff0c;已被广泛应用于各个领域的科学研究以及工程计算&#xff0c;为工程界和科学界解决了复杂的多物理场建模问题。光电作为物理类专业课程中极为重要的一部分&#xff0c;其教学内…

如何做到设备维护事半功倍?

在工业生产过程中&#xff0c;设备故障可能导致生产停机、成本增加和安全风险。因此&#xff0c;及时监测设备的健康状况&#xff0c;预测潜在故障&#xff0c;并采取相应的维护措施至关重要。 振动在线监测系统是一种有效的工具&#xff0c;可以实时监测设备振动&#xff0c;并…

3. Linux下实现统计文件单词个数和出现次数

本文介绍的是在Linux下实现统计文件单词个数和出现次数&#xff0c;以及实践过程中遇到的gcc编译器不匹配问题 一、实现文件单词个数统计 #include <stdio.h>#define IN_Word 1 #define OUT_Word 0 #define INIT OUT_Wordint splite(char c){if ((c ) || (c\n) || (c\t…

ChatGPT ?、AI 和机器人,是为人类打工还是将取代人类?

随着ChatGPT引起全球热潮&#xff0c;我们看到这类AI大模型技术比较热门的落地领域聚焦在办公平台、家庭、电商营销、社交文娱等多个方向&#xff0c;又进一步向下渗透到生产和生活的各个环节。这些场景大多数聚焦于线上&#xff0c;涉及内容创作和交互方式变革两个方向&#x…

【全网首发】华秋CAM:免费Gerber查看器,离线版!

自华秋DFM可制造性和组装性分析软件上线以来&#xff0c;已为众多硬件工程师、PCB工程师、CAM工程师、电子爱好者、PCBA采购、SMT工厂等众多行业用户&#xff0c;解决了各种PCB设计隐患和规避各类生产风险等问题&#xff0c;并获得了30万用户的一致好评&#xff01; 现在&…

双非渣本测试,3个月逆袭字节,入职那天“泪目”了

个人背景情况 2017 年毕业于一所不知名双非本科大学&#xff0c;毕业时就有着一颗想进大厂的心&#xff0c;但又想留在成都&#xff0c;不愿意去北上广&#xff0c;现在其实相当后悔。当年在成都的大厂少之又少&#xff0c;再加上校招时非常努力地玩耍&#xff0c;导致投的几个…