springboot+mybatisplus实现分页

news2025/1/11 6:03:37

在日常开发中,多记录的列表查询可能会遇到分页处理的场景,在springboot项目中传统是引入mybatis组件进行持久化,然后通过pagehelper组件进行分页实现。下面体验一下在springboot项目中引入mybatisplus组件,通过其自带分页插件实现分页功能。

1、MyBatis Plus

MyBatis Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
Mybatis Plus可以节省大量时间,所有的CRUD代码都可以自动化完成。MyBatis Plus自带分页插件(即BaseMapper接口中的selectPage()方法),只要简单的配置即可实现分页功能。
在这里插入图片描述

2、springboot+mybatisplus+mysql实例

pom.xml文件中引入依赖

		<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
        </dependency>

添加分页配置类

@Configuration
public class MybatisPlusConfig {

    /**
     * 分页插件(官网最新)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

}

添加service层代码,分页的所有数据都在userPage对象中封装着,所以可以调用userPage对象的一系列方法对分页数据进行操作。

@Slf4j
@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper userMapper;

    @Override
    public Page<User> listPage1(Page<User> page, QueryWrapper<User> queryWrapper) {
        return userMapper.selectPage(page, queryWrapper);
    }

    @Override
    public PagerModel<User> listPage2(Page<User> page, QueryWrapper<User> queryWrapper) {
        Page<User> userIPage = userMapper.selectPage(page, queryWrapper);
        // 分页的所有数据都在userPage对象中封装着
        // 获取总页数
        long pages = userIPage.getPages();
        //一页显示几条数据
        long size = userIPage.getSize();
        // 获取当前页
        long current = userIPage.getCurrent();
        // 获取当前页数据集合
        List<User> records = userIPage.getRecords();
        // 获取总记录数
        long total = userIPage.getTotal();
        // 当前页是否有下一页
        boolean hasNext = userIPage.hasNext();
        // 当前页是否有上一页
        boolean hasPrevious = userIPage.hasPrevious();

        System.out.println("总页数pages=" + pages);
        System.out.println("当前页current=" + current);
        System.out.println("当前页显示几条数据size=" + size);
        System.out.println("当前页数据集合records=" + records);
        System.out.println("总记录数total=" + total);
        System.out.println("是否有下一页hasNext=" + hasNext);
        System.out.println("是否有上一页hasPrevious=" + hasPrevious);
        return new PagerModel<>(userIPage.getTotal(), records);
    }
}

添加controller层代码

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private SysUserService userService;

	/**
     * 分页列表
     * @param keyword
     * @param pageNum
     * @param pageSize
     * @return
     */
    @GetMapping("/listPage1")
    public Page<User> listPage1(@RequestParam(value = "keyword", defaultValue = "") String keyword,
                                  @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                                  @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize) {
        // 条件构造器
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 模糊查询Like
        queryWrapper.like("nickname", keyword);
        // 分页插件
        Page<User> page = new Page(pageNum, pageSize);
        // 查询数据
        return userService.listPage1(page, queryWrapper);
    }

    /**
     * 自定义分页对象,分页列表
     * @param keyword
     * @param pageNum
     * @param pageSize
     * @return
     */
    @GetMapping("/listPage2")
    public PagerModel<User> listPage2(@RequestParam(value = "keyword", defaultValue = "") String keyword,
                                 @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                                 @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize) {
        // 条件构造器
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 模糊查询Like
        queryWrapper.like("nickname", keyword);
        // 分页插件
        Page<User> page = new Page(pageNum, pageSize);
        // 查询数据
        return userService.listPage2(page, queryWrapper);
    }
    
}

自定义列表返回对象

@Data
@Builder(toBuilder = true)
public class PagerModel<T> implements Serializable {
    private static final long serialVersionUID = 4804053559968742915L;
    /**
     * 总记录数
     */
    private long total;
    /**
     * 每页的查询结果集
     */
    private List<T> rows = new ArrayList();
    /**
     * 获取总页数
     */
    private long pages;
    /**
     * 获取当前页
     */
    private long current;
    /**
     * 当前页显示几条数据
     */
    private long size;
    /**
     * 当前页是否有下一页
     */
    private boolean hasNext;
    /**
     * 当前页是否有上一页
     */
    private boolean hasPrevious;

    public PagerModel() {
    }

    public PagerModel(long total, List<T> rows) {
        this.total = total;
        this.rows = rows;
    }

    public PagerModel(long total, List<T> rows, long pages, long current) {
        this.total = total;
        this.rows = rows;
        this.pages = pages;
        this.current = current;
    }

    public PagerModel(long total, List<T> rows, long pages, long current, long size) {
        this.total = total;
        this.rows = rows;
        this.pages = pages;
        this.current = current;
        this.size = size;
    }

    public PagerModel(long total, List<T> rows, long pages, long current, boolean hasNext, boolean hasPrevious) {
        this.total = total;
        this.rows = rows;
        this.pages = pages;
        this.current = current;
        this.hasNext = hasNext;
        this.hasPrevious = hasPrevious;
    }

    public PagerModel(long total, List<T> rows, long pages, long current, long size, boolean hasNext, boolean hasPrevious) {
        this.total = total;
        this.rows = rows;
        this.pages = pages;
        this.current = current;
        this.size = size;
        this.hasNext = hasNext;
        this.hasPrevious = hasPrevious;
    }
}

3、测试

访问:http://localhost:8805/first/user/listPage1,结果如下
在这里插入图片描述
访问:http://localhost:8805/first/user/listPage2,结果如下
在这里插入图片描述
日志打印如下
在这里插入图片描述

4、异常:java.sql.SQLFeatureNotSupportedException

异常信息如下

Caused by: java.sql.SQLFeatureNotSupportedException: null
	at com.alibaba.druid.pool.DruidPooledResultSet.getObject(DruidPooledResultSet.java:1771)
	at com.p6spy.engine.wrapper.ResultSetWrapper.getObject(ResultSetWrapper.java:1649)
	at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:38)
	at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:28)
	at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:81)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.applyAutomaticMappings(DefaultResultSetHandler.java:521)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:402)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:354)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:328)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:301)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:194)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
	at com.sun.proxy.$Proxy247.query(Unknown Source)
	at com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor.doQuery(MybatisSimpleExecutor.java:67)
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:136)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426)
	... 106 common frames omitted

出现上述异常是由于druid和Mybatis plus依赖版本的问题。
druid版本在1.1.21之前是不支持LocalDateTime等新日期处理方式的,但是Mybatis plus在3.3.1之后是支持的。因此在SQL查询过程中,这两者就产生了冲突。
解决方法:把druid版本提高到1.2.6(不建议降低Mybatis plus版本),改完之后,异常解决。注:确保项目中的依赖或隐藏依赖中的druid版本提高到1.1.21版本以上。

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

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

相关文章

cpu简述--指令集架构

很多初级开发者其实都对cpu了解不多&#xff0c;个人兴趣原因想要了解一下cpu的相关知识&#xff0c;所以开几篇文章记录一下吧。 2002年8月10日,中国科学院计算技术研究所的青年科学家胡伟武带领研制组,研制出我国首枚拥有自主知识产权的通用高性能微处理芯片——“龙芯一…

MindOpt安装配置教程(Windows系统)

1 前言 官网有很多的说明文档、教程&#xff0c;但是可能有些地方&#xff08;这里仅仅补充安装配置部分&#xff0c;其他操作建议自行去官网进行探索&#xff09;不是很详细&#xff0c;踩了一些坑&#xff0c;所以进行了一些总结。 2 下载安装 url&#xff1a;求解器SDK下载…

Nginx基础02:配置文件nginx.conf(Part1)

我们使用Nginx主要是通过其配置文件nginx.conf来实现的。按照一定的规则&#xff0c;编写特定的指令&#xff0c;可以帮助我们实现对Web服务的控制&#xff01;所以&#xff0c;学习Nginx的用法&#xff0c;几乎就是学习nginx.conf&#xff01;如何使用本篇文章本文作为一篇高度…

【博客590】iptables raw表的特殊作用

iptables raw表的特殊作用 1、iptables四表五链&#xff1a; 2、raw表的优先级 从上图中可以看到raw表作用于prerouting和output链&#xff0c;且在这两个链中的几个表中拥有最高优先级&#xff0c;并且是高于连接跟踪的&#xff0c;这个也是raw表用于优化性能的一个重要前提 …

Leetcode链表专题专练-万字总结

文章目录 系列&#xff1a;链表专练 语言&#xff1a;java & go 题目来源&#xff1a;Leetcode 常考点&#xff1a; 单链表 & 双链表 &双指针 思路和参考答案文章目录链表专题总结链表专练链表专题总结 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个…

【计算机网络】传输层协议-------TCP详解

文章目录1. TCP 协议概述2. TCP原理2.1 保持可靠性的机制2.1.1 确认应答2.1.2 超时重传2.1.3 连接管理机制(安全机制)2.1.3.1 三次握手2.1.3.2 四次挥手2.1.4 滑动窗口2.1.5 流量控制2.1.6 拥塞控制2.1.7延时应答2.1.8 捎带应答2.1.9 粘包问题2.1.10 TCP异常2.1.11 TCP vs UDP1…

记录每日LeetCode 112.路径总和 Java实现

题目描述&#xff1a; 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 叶…

马蜂窝如何利用 APISIX 网关实现微服务架构升级

作者&#xff1a;董红帅&#xff0c;马蜂窝微服务体系建设以及基础服务能力建设专家。 马蜂窝作为旅行社交平台&#xff0c;是数据驱动的新型旅行电商。基于十余年的内容积累&#xff0c;马蜂窝通过 AI 技术与大数据算法&#xff0c;将个性化旅行信息与来自全球各地的旅游产品供…

Water Pamola通过恶意订单对电商发起攻击

自2019年以来&#xff0c;趋势科技的研究人员一直在追踪一个被称为“Water Pamola”的攻击活动。该活动最初通过带有恶意附件的垃圾邮件攻击了日本、澳大利亚和欧洲国家的电子商务在线商店。 但是&#xff0c;自2020年初以来&#xff0c;研究人员注意到Water Pamola的活动发生…

(二十三)Collecttion集合

目录 前言: ①Collecttion集合的体系结构 ②Collecttion集合的遍历方式 方式一:迭代器 方式二:foreach/增强for循环 方式三:Lambda表达式 ③常见数据结构 前言: Collection&#xff1a; 是所有集合的顶级接口,里面规定了集合操作元素的相关功能方法集合与数组一样,用于存储一组…

使用Sa-token实现单点登录

使用Sa-token实现单点登录单点登录需求为何选择Sa-Token简单使用sa-token接口如何保持登录态使用拦截器实现鉴权聊聊Sa-Token的理解聊聊遇到的一些问题单点登录需求 其实一直想写一个单点登录系统&#xff0c;现在的现状是公司内部有非常多项目的&#xff0c;然后每个项目一套登…

数据分析面试题--数理知识点1

目录标题1&#xff0c;python统计一段话每个单词出现的次数2&#xff0c;SQL中如何利用replace函数统计给定重复字段在字符串中的出现频率&#xff1f;3&#xff0c;常见的统计分析方法有哪些&#xff1f;拿到数据如何分析4&#xff0c;参数估计和假设检验的联系和区别5&#x…

网络实验之OSPF路由协议(一)

一、OSPF路由协议简介 开放式最短路径优先&#xff08;Open Shortest Path First&#xff0c;OSPF&#xff09;路由协议是用于网际协议&#xff08;IP&#xff09;网络的链路状态路由协议。该协议使用链路状态路由算法的内部网关协议&#xff08;IGP&#xff09;&#xff0c;在…

NIO笔记

一. NIO 基础 non-blocking io 非阻塞 IO 1. 三大组件 1.1 Channel & Buffer channel 有一点类似于 stream&#xff0c;它就是读写数据的双向通道&#xff0c;可以从 channel 将数据读入 buffer&#xff0c;也可以将 buffer 的数据写入 channel&#xff0c;而之前的 st…

SAP ABAP 代码修改自动比较对象版本一致

第一步&#xff0c;找到SE38/SE37代码修改的出口 SMOD中查找 第二步&#xff0c;实施增强 CMOD中添加增强并激活&#xff0c;如下图 第三步&#xff0c;添加代码 如上图两个双击添加并修改代码 ZXSEUU08中与 ZXSEUU01代码一致&#xff0c;如下 *&----------------------…

【年度总结】我的2022年-职业生涯大转折

【年度总结】我的2022年-职业生涯大转折2022总结大厂的苦与乐找工作的焦虑再起启航2023展望持续刷题持续学习捡起博客在漩涡中疯狂挣扎的一年 2022总结 大厂的苦与乐 上半年主要在搞中台&#xff0c;需要对接的其他团队比较多&#xff0c;每天都在对接需求、优化需求。同时还…

Python NumPy 创建数组(ndarray)

前言NumPy&#xff08;Numerical Python的缩写&#xff09;是一个开源的Python科学计算库。使用NumPy&#xff0c;就可以很自然地使用数组和矩阵。NumPy包含很多实用的数学函数&#xff0c;涵盖线性代数运算、傅里叶变换和随机数生成等功能。本文主要介绍使用Python NumPy 创建…

鉴源论坛 · 观辙丨基于机器学习的汽车CAN总线异常检测方法

作者 | 张渊策 上海控安可信软件创新研究院研发工程师 来源 | 鉴源实验室 目前机器学习是研究车辆网络入侵检测技术的热门方向&#xff0c;通过引入机器学习算法来识别车载总线上的网络报文&#xff0c;可实现对车辆已知/未知威胁的入侵检测。这种基于机器学习的异常检测技术普…

chrono_duration(一)

文章目录chrono简介std::chrono::durationduratio基本介绍基本概念使用引入std::ratio 参数深入特化的duratio改造之前的代码静态成员函数 count原型例子构造函数支持加减乘除运算编译细节支持比较运算符查询范围类型转换例子引入修改seconds的范围浮点类型系统特化的duratio自…

os模块的使用方法详解

os模块os模块负责程序与操作系统的交互&#xff0c;提供了访问操作系统底层的接口&#xff1b;即os模块提供了非常丰富的方法用来处理文件和目录。使用的时候需要导入该模块&#xff1a;import os常用方法如下&#xff1a;方法名作用os.remove(‘path/filename’)删除文件os.re…