Mybatis分页框架-PageHelper

news2024/11/16 6:50:22

Mybatis分页框架-PageHelper

  • 一、PageHelper基础使用
    • 1.引入jar包
    • 2.配置conifg
    • 3.测试使用
  • 二、PageHelper的多种用法
    • 1.使用PageHelper.startPage传入对象
    • 2.不使用PageHelper.startPage,而使用PageHelper.offsetPage
    • 3.使用Lambda进行分页
    • 4.不使用PageHelper直接分页
    • 5.想要使用分页接口查询全部数据
    • 6.输入异常页码,也支持分页

这篇文章用以总结PageHelper分页插件的使用,PageHelper是Mybatis的分页插件,他的实现原理是基于Mybatis的拦截器QueryInterceptor 来实现的,通过拦截sql查询,来对sql进行增强改造,其实这种思想比比皆是。比如MP的分页插件也是这种思想,比如各种组件里的Interceptor也都是这种思想。这里总结下常用的用法。

一、PageHelper基础使用

java里常用的分页组件都是物理分页,基本没有逻辑分页。PageHelper也是物理分页插件。物理分页就是使用sql直接对数据进行分页处理,逻辑分页时数据全部查出来,然后再进行分页,这样再数据量大时,内容根本扛不住(除非系统比较小)。所以真正使用时都是使用PageHelper这种物理分页插件

1.引入jar包

没啥好说的,使用maven进行引入jar包,官方文档推荐使用最新版jar包,这里可以通过官网看看最新版是多少,如下图:
文章写作时间:2023-09-22
PageHelper最新版本:5.3.3
官网地址: PageHelper官网
本文使用Springboot版本:2.4.4
在这里插入图片描述

        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.3.3</version>
            <!-- 分页插件只会在编译期有用,这里可以声明为compile -->
            <scope>compile</scope>
        </dependency>

2.配置conifg

使用PageHelper必须配置他的分页拦截器PageInterceptor,这个分页拦截器正是使用PageHelper实现分页的关键。最主要的一点是需要我们指定数据库的方言(通俗说就是数据库的类型),因为不同数据库的分页实现是不同的,所以我们需要指明数据库这样PageHelper才可以帮助我们进行动态调整SQL。他具有以下配置项。
注意:如果不配置这个官方文档说也可以自己识别数据库方言,但笔者不配置时发现分页无法生效,验证了5.3.3 和 5.1.11 两个版本都是无法正常分页的,所以还是加上这个配置最好

import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Properties;

/**
 * @author pcc
 * 这是分页插件PageHelper的配置信息
 * 使用PageHelper的原因是MP的分页对于多表分页查询和自定义查询的分页支持不够优秀
 */
@Configuration
public class PageHelperConfig {

    /**
     * 可能存在多个连接工厂,是允许这么注入的
     */
    @Resource
    private List<SqlSessionFactory> sqlSessionFactoryList;

    @PostConstruct
    public void initConfig(){
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        // 设置数据源方言,使用mysql
        properties.setProperty("helperDialect","mysql");
        
        pageInterceptor.setProperties(properties);
        sqlSessionFactoryList.forEach(factory ->factory.getConfiguration().addInterceptor(pageInterceptor));
    }
}

以上就完成了所有配置了,其实非常简单易用。

3.测试使用

使用其实也很简单,不过需要注意以下两点:

    1. 只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询(Select)方法会被分页。
    1. 不支持带有for update语句的分页
    1. 使用下面这种分页方式,查询方法返回结果必须是List<T>,因为PageHelper分页返回的对象是ArrayList类型的Page

下面是分页的代码:

    /**
     * 使用 PageHelper进行分页
     * @param tbTaskItemsVO 入参
     * @return 返回
     */
    @PostMapping("/getTaskItemsPage2")
    public PageInfo<TbTaskItems> getTaskItems2(TbTaskItemsVO tbTaskItemsVO){
        PageHelper.startPage(tbTaskItemsVO.getPageNum(),tbTaskItemsVO.getPageSize());
        List<TbTaskItems> itemsList = iTbTaskItemsService.queryItems();
        PageInfo<TbTaskItems> pageInfo = new PageInfo<>(itemsList);
        return pageInfo;
    }

上面代码就可以正常实现分页了:
在这里插入图片描述
可以看到我们分页的关键信息都是正确的了,使用起来很简单,不过还是有几点需要说明下:

  • 1.PageHelper.startPage 传入的是pageNum,pageSize
  • 2.查询方法(这里是iTbTaskItemsService.queryItems)返回类型必须是ArrayList<T>或他的父类,这里虽然是使用List接收的返回值,看着和原方法没有区别,其实这里的iTbTaskItemsService.queryItems返回参数其实是Page,因为Page是ArrayList的子类所以可以这么写,所以我们方法定义时需要定义返回类型是ArrayList或者他的父类。

二、PageHelper的多种用法

实际工作场景中基本都是使用第一节中的用法就完全足够了,这里做下扩展,说下PageHelper的其他常用写法。下面前几种是比较常用的写法,除了这几种以外还可以支持传入RowBound,或者写查询方法声明分页参数,不过这两种不常用就不说了,感兴趣可以看官方文档:
PageHelper官方文档

1.使用PageHelper.startPage传入对象

这里使用和第一种区别不大,传入对象是第一种的重载方法,传入的对象就一个要求必须有pageNum、pageSize两个参数,且不能为空,这样也可以正常分页。

// 对于上面的写法就动如下代码即可:
PageHelper.startPage(tbTaskItemsVO);

2.不使用PageHelper.startPage,而使用PageHelper.offsetPage

这种写法和上面PageHelper.startPage(offSet,limit)的意义是从offSet的下标开始取数,取limit条数据,这种分页还得我们计算,比第一种稍微麻烦一些。

PageHelper.startPage(pageNum*PageSize,PageSize);

3.使用Lambda进行分页

PageHelper还支持Java8的lambda的写法,只要支持Java8肯定也支持匿名内部类的写法,这里就只展示Java8的写法了,Java7没有什么区别了

    /**
     * 使用 PageHelper进行分页
     * @param tbTaskItemsVO 入参
     * @return 返回
     */
    @PostMapping("/getTaskItemsPage2")
    public PageInfo<TbTaskItems> getTaskItems2(TbTaskItemsVO tbTaskItemsVO){
    
        PageInfo<TbTaskItems> objectPageInfo = PageHelper.startPage(tbTaskItemsVO).doSelectPageInfo(() -> {
            iTbTaskItemsService.queryItems();
        });
        return objectPageInfo;
    }

4.不使用PageHelper直接分页

这种写法需要增加一个PageInterceptor的配置项,才可以支持,默认是不支持的,这种写法最简单,会让写代码的看不到分页的任何痕迹,但是这样反而不好,容易让人忽略,但是这种写法最简洁。

  • 1.新增配置项
// 配置supportMethodsArguments=true
// 分页插件会从查询方法的参数值中寻找pageNum,pageSize进行分页,找到就可以进行分页
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Properties;

/**
 * @author pcc
 * 这是分页插件PageHelper的配置信息
 * 使用PageHelper的原因是MP的分页对于多表分页查询和自定义查询的分页支持不够优秀
 */
@Configuration
public class PageHelperConfig {

    /**
     * 可能存在多个连接工厂,是允许这么注入的
     */
    @Resource
    private List<SqlSessionFactory> sqlSessionFactoryList;

    @PostConstruct
    public void initConfig(){
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        // 设置数据源方言,使用mysql
        properties.setProperty("helperDialect","mysql");
        // 支持自动分页,需要保证查询方法的对象中必须含有pageNum,pageSize
        properties.setProperty("supportMethodsArguments","true");
        
        pageInterceptor.setProperties(properties);
        sqlSessionFactoryList.forEach(factory ->factory.getConfiguration().addInterceptor(pageInterceptor));
    }
}
  • 2.查询方法需要修改为传递对象或者Map也是可以的,不过都必须含有pageNum,pageSize才可以。
    /**
     * 使用 PageHelper进行分页
     * @param tbTaskItemsVO 入参
     * @return 返回
     */
    @PostMapping("/getTaskItemsPage2")
    public PageInfo<TbTaskItems> getTaskItems2(TbTaskItemsVO tbTaskItemsVO){
        List<TbTaskItems> itemsList = iTbTaskItemsService.queryItems(tbTaskItemsVO);
        PageInfo<TbTaskItems> pageInfo = new PageInfo<>(itemsList);
        return pageInfo;
    }

5.想要使用分页接口查询全部数据

需要新增一个配置参数:pageSizeZero=true,配置这个参数后如果想要查询全部数据,只需要传递pageSize=0,就会默认查询全部数据,不过返回的还是Page信息。

// 只展示配置信息
public void initConfig(){
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        // 设置数据源方言,使用mysql
        properties.setProperty("helperDialect","mysql");
        // 支持自动分页,需要保证查询方法的对象中必须含有pageNum,pageSize
        properties.setProperty("supportMethodsArguments","true");
        // 支持查询全部信息
        properties.setProperty("pageSizeZero","true");
        
        pageInterceptor.setProperties(properties);
        sqlSessionFactoryList.forEach(factory ->factory.getConfiguration().addInterceptor(pageInterceptor));
    }

其他使用则没有区别了,就不重复举例了

6.输入异常页码,也支持分页

当输入异常页码也可以支持进行分页,需要增加配置:reasonable=true,当增加这个配置后,当pageNum<=0时,会查询第一页,pageNum>最大页,会查询最后一页。当然pageSize必须有值。

// 只展示配置信息
public void initConfig(){
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        // 设置数据源方言,使用mysql
        properties.setProperty("helperDialect","mysql");
        // 支持自动分页,需要保证查询方法的对象中必须含有pageNum,pageSize
        properties.setProperty("supportMethodsArguments","true");
        // 支持查询全部信息
        properties.setProperty("pageSizeZero","true");
        // 支持异常页码查询
        properties.setProperty("reasonable","true");
        
        pageInterceptor.setProperties(properties);
        sqlSessionFactoryList.forEach(factory ->factory.getConfiguration().addInterceptor(pageInterceptor));
    }

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

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

相关文章

代码随想录算法训练营 动态规划part17

一、回文子串 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int countSubstrings(String s) {boolean[][] dp new boolean[s.length()][s.length()];int ans 0;for (int j 0; j < s.length(); j) {for (int i 0; i < j; i) {if …

5+铁死亡+分型+WGCNA+机器学习分析

今天给同学们分享一篇铁死亡分型WGCNA机器学习的生信文章“Identification of ferroptosis-related molecular clusters and genes for diabetic osteoporosis based on the machine learning”&#xff0c;这篇文章于2023年8月14日发表在Front Endocrinol (Lausanne)期刊上&am…

Nginx location 精准匹配URL = /

Location是什么&#xff1f; Location是Nginx中的块级指令(block directive)&#xff0c;通过配置Location指令块&#xff0c;可以决定客户端发过来的请求URI如何处理&#xff08;是映射到本地文件还是转发出去&#xff09;及被哪个location处理。 匹配模式 分为两种模式&…

Zookeeper-命令操作

命令操作 命令操作1) Zookeeper 数据模型2) Zookeeper 服务端常用命令3) Zookeeper 客户端常用命令 命令操作 1) Zookeeper 数据模型 ZooKeeper 是一个树形目录服务,其数据模型和Unix的文件系统目录树很类似&#xff0c;拥有一个层次化结构。 这里面的每一个节点都被称为&am…

OpenCV实现图像 开闭运算

开运算概念 闭运算概念 API cv.morphologyEx(img , op, kernal) 参数&#xff1a; img ;要处理的图像op : 处理方式 &#xff1a; 若进行开运算&#xff0c;则设为cv.MORPH_OPEN &#xff0c;若进行闭运算&#xff0c;则设为cv.MORPH_CLOSEKernel &#xff1a;核结构 代码实现…

面试题:RocketMQ 如何保证消息不丢失,如何保证消息不被重复消费?

文章目录 1、消息整体处理过程Producer发送消息阶段手段一&#xff1a;提供SYNC的发送消息方式&#xff0c;等待broker处理结果。手段二&#xff1a;发送消息如果失败或者超时&#xff0c;则重新发送。手段三&#xff1a;broker提供多master模式&#xff0c;即使某台broker宕机…

【STM32单片机】小恐龙游戏设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用STM32F103C8T6单片机控制器&#xff0c;使用按键、IIC OLED模块等。 主要功能&#xff1a; 系统运行后&#xff0c;OLED液晶显示游戏初始界面&#xff0c;按下K4键开始&#xff0c;K1键跳跃&am…

Twitter优化秘籍:置顶、列表、受众增长

在 Twitter 上&#xff0c;将你的一条推送文置顶到个人数据顶部是提高可见性和吸引关注者的绝佳方式。无论你是个人用户还是企业&#xff0c;此功能都可以让你的重要信息常驻在众人眼前&#xff0c;即使你发布了新的推文。接下来&#xff0c;我们将分享一些优化建议&#xff0c…

机器视觉工程师们,常回家看看

我们在这个社会上扮演着多重角色&#xff0c;有时候我们很难平衡好这些角色之间的关系。 人们常言&#xff0c;积善成德&#xff0c;改变命运。善修者&#xff0c;懂得积累&#xff0c;懂得改变命运的重要性。 我曾年少不知父母之不易。一路依靠&#xff0c;一路成长。 所谓…

【数据增强】

【数据增强】 1 数据增强的情形2 数据增强的方法 1 数据增强的情形 当数据比较小&#xff0c;难以获取新的训练数据时&#xff0c;可以考虑数据增强&#xff0c;如随机裁剪部分&#xff0c;随机左右上下翻转、随机旋转一个角度、随机亮度变化等微小变化&#xff0c;数据的多样…

conan入门(二十七):因profile [env]字段废弃导致的boost/1.81.0 在aarch64-linux-gnu下交叉编译失败

今天在尝试用conan 1.60.0使用aarch64-linux-gnu编译器交叉编译boost/1.81.0时报错了&#xff1a; conan install boost/1.81.0 -pr:h aarch64-linux-gnu.jinja -pr:b default --build boost输出如下&#xff1a; Configuration (profile_host): [settings] archarmv8 arch_b…

iOS——present相关属性以及dismiss多级的方法

push和present 两者的区别 push: push由视图栈控制&#xff0c;每一个视图都入栈&#xff0c;调用之前的视图则需要出栈&#xff0c;可返回任意一层&#xff0c;一般用于同一业务不同界面之间的切换。 push是由UINavigationController管理的视图控制器堆栈&#xff0c;在wind…

CSS3实现上下拉长加载动画效果

上下拉长加载动画效果 <!DOCTYPE html> <html><head><style>.container {display: flex;justify-content: center;align-items: center;width: 150px;height: 150px;margin: 50px auto;}.rectangle {width: 20px;height: 50px;background-color: #02A…

黑马JVM总结(十九)

&#xff08;1&#xff09;GC调优1 通过官网查看查看JVM的参数&#xff1a; 可以使用java命令查看当前环境下的虚拟机参数&#xff1a; 学会使用一些工具如前面学的jmap &#xff0c;jconsole等等工具 &#xff08;2&#xff09;GC调优2 垃圾回收调优只是众多调优中的一个方…

基于微信小程序的电动车智能充电系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境说明用户的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌…

THREE.JS 3D模型服务器报404问题(VUE fbx文件在本地能显示 服务器上不显示报404)

问题&#xff1a; 作为新手&#xff0c;新建立的threeJS模型&#xff0c;本地运行模型是可以显示的 &#xff0c;但服务器模型却报404 写法&#xff1a; fbxloader("TR7007Q").then((tree) > { tree.position.set(-1080, -20, 0);this.$refs.draw.scene.add(tree…

编辑.htaccess文件执行任意代码(CVE-2022-25578)

简介 CVE-2022-25578是Taocms v3.0.2中存在的一个安全漏洞&#xff0c;该漏洞允许攻击者通过任意编辑.htaccess文件来执行代码注入攻击。 Taocms是一个完善支持多数据库&#xff08;Sqlite/Mysql&#xff09;的CMS网站内容管理系统&#xff0c;是国内最小且功能完善的基于php…

DM/达梦数据库查询或更新某一列中多个字典码对应内容

准备工作&#xff08;建表、插入数据&#xff09; 1、建立表格&#xff1a;学生-学习科目表student_study 注意&#xff1a;科目kemu列内容是字典码&#xff0c;需要更换成对应内容。 CREATE TABLE "TEST"."STUDENT_STUDY" ( "NAME" VARCHAR(2…

技术分享| anyRTC音视频混流技术解析

一&#xff0c;简介 在视频通讯场景中&#xff0c;比如会议、直播等经常能看到图像合成的场景。图像合成是在指定的一块画面区域&#xff0c;在这个区域内&#xff0c;按画面的位置(坐标)布局&#xff0c;将区域中的每个视频画面的像素混合计算成一个像素&#xff08;RGB&…

深度学习中的激活函数 – 完整概述

1.什么是激活函数? 生物神经网络启发了人工神经网络的发展。然而,人工神经网络甚至不能近似代表大脑的工作方式。在我们知道为什么在人工神经网络中使用激活函数之前,了解生物神经网络中激活函数的相关性仍然很有用。 典型的神经元具有由细胞体、向其他神经元发送信息的轴…