Spring Boot集成Mybatis Plus通过Pagehelper实现分页查询

文章目录

  • [0 简要说明Pagehelper](#0 简要说明Pagehelper)
  • [1 搭建环境](#1 搭建环境)
  • [2 可能出现的疑问或者问题](#2 可能出现的疑问或者问题)
    • [2.1 关于total属性疑问](#2.1 关于total属性疑问)
    • [2.2 分页不生效问题](#2.2 分页不生效问题)
  • [3 案例说明](#3 案例说明)
    • [3.1 配置信息](#3.1 配置信息)
    • [3.2 请求体](#3.2 请求体)
    • [3.3 控制层](#3.3 控制层)
    • [3.5 业务层](#3.5 业务层)
    • [4.6 业务层实现类](#4.6 业务层实现类)
  • [4 关键问题:查询和录入操作使用一个dto出现强制分页情况【待定,问题未能复现,请稍等】](#4 关键问题:查询和录入操作使用一个dto出现强制分页情况【待定,问题未能复现,请稍等】)

解决 PageInfo 返回的 total 不正确
关于PageInfo的total属性得到的值等于当前页记录数
Pagehelper官网
Pagehelper使用入门

0 简要说明Pagehelper

1 搭建环境

1.1 项目目录

1.2 项目搭建需要的依赖

xml 复制代码
		 <!-- SpringBoot的依赖配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.5.10</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        <!--Mybatis Plus 核心依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--MySQL驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <!--Mybatis Plus 扩展依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-extension</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--pagehelper分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.0</version>
        </dependency>

1.3 配置分页插件拦截器

在properties或者yml配置拦截器信息,使其生效。

Spring Boot 引入 starter 后自动生效,对分页插件进行配置时,在 Spring Boot 对应的配置文件 application.[properties|yaml] 中配置

yml 复制代码
# DataSource Config
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true&serverTimezone=UTC&useSSL=false&allowMultiQueries=true
    driver-class-name: com.mysql.cj.jdbc.Driver
  mvc:
    pathmatch:
      matching-strategy: ANT_PATH_MATCHER

#配置日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath:mapper/*.xml

server:
  port: 8089

pagehelper:
  reasonable: true
  support-methods-arguments: true
  params: countSql
  helperDialect: mysql

reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。

supportMethodsArguments:支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTestArgumentsObjTest

helperDialect:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。

params:为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值, 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero

更加详细的参数说明,可以参考官网说明

1.4 源代码

启动类

java 复制代码
package com.geekmice.sbpagehelper;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @BelongsProject: spring-boot-scaffold
 * @BelongsPackage: PACKAGE_NAME
 * @Author: pingmingbo
 * @CreateTime: 2023-08-05  15:14
 * @Description: TODO
 * @Version: 1.0
 */
@MapperScan(value = "com.geekmice.sbpagehelper.dao")
@SpringBootApplication
public class SbPageHelperApplication {
    public static void main(String[] args) {
        SpringApplication.run(SbPageHelperApplication.class, args);
    }
}

实体类

java 复制代码
package com.geekmice.sbpagehelper.domain;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;

/**
 * (Teacher)实体类
 *
 * @author pingmingbo
 * @since 2023-08-05 15:19:26
 */
@TableName("teacher")
@Data
public class Teacher implements Serializable {
    private static final long serialVersionUID = -82982716139385175L;
    /**
     * 教师号
     */
    @TableId
    @TableField(value = "teacher_no")
    private String teacherNo;

    /**
     * 教师名称
     */
    @TableField(value = "teacher_name")
    private String teacherName;

    /**
     * 部门编号
     */
    @TableField(value = "category_id")
    private Integer categoryId;


}

数据层

java 复制代码
package com.geekmice.sbpagehelper.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.geekmice.sbpagehelper.domain.Teacher;
import org.apache.ibatis.annotations.Param;
import java.util.List;

/**
 * (Teacher)表数据库访问层
 *
 * @author pingmingbo
 * @since 2023-08-05 15:19:26
 */
public interface TeacherDao extends BaseMapper<Teacher> {


}

xml映射文件

xml 复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.geekmice.sbpagehelper.dao.TeacherDao">
    
        <resultMap type="com.geekmice.sbpagehelper.domain.Teacher" id="TeacherMap">
            <result property="teacherNo" column="teacher_no" jdbcType="VARCHAR"/>
            <result property="teacherName" column="teacher_name" jdbcType="VARCHAR"/>
            <result property="categoryId" column="category_id" jdbcType="INTEGER"/>
        </resultMap>
    

    
    </mapper>

业务层

java 复制代码
package com.geekmice.sbpagehelper.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.geekmice.sbpagehelper.domain.Teacher;
import com.geekmice.sbpagehelper.dto.QueryDTO;
import com.github.pagehelper.PageInfo;

import java.util.List;

/**
 * (Teacher)表服务接口
 *
 * @author pingmingbo
 * @since 2023-08-05 15:19:26
 */
public interface TeacherService extends IService<Teacher> {


    /**
     * @return 响应信息
     * @description 初次使用分页查询
     */
    List<Teacher> queryPage();

    /**
     * @param pageSize 当前页数
     * @param pageNum  每页条数
     * @return 返回信息
     * @description 分页参数查询
     */
    PageInfo<Teacher> queryPage(int pageNum, int pageSize);

    /**
     * @param queryDTO 请求体
     * @return 响应信息
     * @description 多参数分页查询
     */
    PageInfo<Teacher> queryPage(QueryDTO queryDTO);
}

业务层实现类

java 复制代码
package com.geekmice.sbpagehelper.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geekmice.sbpagehelper.dao.TeacherDao;
import com.geekmice.sbpagehelper.domain.Teacher;
import com.geekmice.sbpagehelper.dto.QueryDTO;
import com.geekmice.sbpagehelper.service.TeacherService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * (Teacher)表服务实现类
 *
 * @author pingmingbo
 * @since 2023-08-05 15:19:26
 */
@Service("teacherService")
@Slf4j
public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> implements TeacherService {
    @Resource
    private TeacherDao teacherDao;

    /**
     * @return 响应信息
     * @description 初次使用分页查询
     */
    @Override
    public List<Teacher> queryPage() {
        PageHelper.startPage(1, 10);
        List<Teacher> result = teacherDao.selectList(null);
        return result;
    }

    /**
     * @param pageSize 当前页数
     * @param pageNum  每页条数
     * @return 返回信息
     * @description 分页参数查询
     */
    @Override
    public PageInfo<Teacher> queryPage(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
        teacherQueryWrapper.likeRight("teacher_name", "小");
        List<Teacher> teachers = teacherDao.selectList(teacherQueryWrapper);
        PageInfo<Teacher> teacherPageInfo = new PageInfo<>(teachers);
        return teacherPageInfo;
    }

    /**
     * @param queryDTO 请求体
     * @return 响应信息
     * @description 多参数分页查询
     */
    @Override
    public PageInfo<Teacher> queryPage(QueryDTO queryDTO) {
        int pageNum = queryDTO.getPageNum();
        int pageSize = queryDTO.getPageSize();
        PageHelper.startPage(pageNum,pageSize);
        QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
        teacherQueryWrapper.eq("teacher_name", queryDTO.getTeacherName());
        List<Teacher> teacherList = teacherDao.selectList(teacherQueryWrapper);
        PageInfo<Teacher> result = new PageInfo<>(teacherList);
        return result;
    }
}

控制层

java 复制代码
package com.geekmice.sbpagehelper.controller;

import com.geekmice.common.utils.AjaxResult;
import com.geekmice.sbpagehelper.domain.Teacher;
import com.geekmice.sbpagehelper.dto.QueryDTO;
import com.geekmice.sbpagehelper.service.TeacherService;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * (Teacher)表控制层
 *
 * @author pingmingbo
 * @since 2023-08-05 15:19:26
 */
@RestController
@RequestMapping("teacher")
@Api(tags = "0.分页查询模块")
public class TeacherController {
    /**
     * 服务对象
     */
    @Resource
    private TeacherService teacherService;

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @ApiOperation(value = "查询单条数据")
    @GetMapping("selectOne")
    public Teacher selectOne(String id) {
        return null;
    }

    /**
     * @return 响应信息
     * @description 初次使用分页查询
     */
    @GetMapping(value = "queryPage")
    @ApiOperation(value = "分页查询")
    public List<Teacher> queryPage() {
        List<Teacher> result = teacherService.queryPage();
        return result;
    }

    /**
     * @param pageSize 当前页数
     * @param pageNum  每页条数
     * @return 返回信息
     * @description 分页参数查询
     */
    @GetMapping(value = "queryPageHavingParams")
    @ApiOperation(value = "分页查询带有参数")
    public AjaxResult queryPageHavingParams(int pageSize, int pageNum) {
        PageInfo<Teacher> result = teacherService.queryPage(pageNum, pageSize);
        return AjaxResult.success(result);
    }

    /**
     * @param queryDTO 请求体
     * @return 响应信息
     * @description 多参数分页查询
     */
    @GetMapping(value = "queryPageByDTO")
    @ApiOperation(value = "多参数分页查询")
    public AjaxResult queryPageByDTO(QueryDTO queryDTO) {
        PageInfo<Teacher> result = teacherService.queryPage(queryDTO);
        return AjaxResult.success(result);
    }

}

接口配置swagger

java 复制代码
package com.geekmice.sbpagehelper.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

/**
 * @BelongsProject: spring-boot-scaffold
 * @BelongsPackage: com.geekmice.sbhelloworld.com.geekmice.sbpagehelper.config
 * @Author: pingmingbo
 * @CreateTime: 2023-07-30  15:45
 * @Description: TODO
 * @Version: 1.0
 */
@Configuration
public class Knife4jConfig {
    @Bean(value = "defaultApi2")
    public Docket customDocket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.geekmice.sbpagehelper.controller"))
                .build();
    }

    /**
     * 构建 api文档的详细信息函数
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("现货交易")
                .version("1.0.0")
                .description("现货交易详情")
                .contact(new Contact("geekmice","http://geekmice.cn","2437690868@qq.com"))
                .build();
    }
}

请求体

java 复制代码
package com.geekmice.sbpagehelper.dto;

import com.github.pagehelper.PageInfo;
import lombok.Data;

/**
 * @BelongsProject: spring-boot-scaffold
 * @BelongsPackage: com.geekmice.sbpagehelper.dto
 * @Author: pingmingbo
 * @CreateTime: 2023-08-05  16:00
 * @Description: TODO
 * @Version: 1.0
 */
@Data
public class QueryDTO extends PageInfo {
    private String teacherName;
}

2 可能出现的疑问或者问题

2.1 关于total属性疑问

2.2 分页不生效问题

  1. 当我们调用pagehelper.startPage()方法后下一条语句必须是你要调用的查询语句;
  2. 我们的PageInfo传入的结果集,必须是我们调用查询语句返回的结果集;

提前说明:入参是 pageNum:1 pageSize:2 userName:张 模糊查询

正常情况,没有分页是有以张开头有三条数据,有分页的情况下 张1,张2

第一种问题复现如下:
List userDomainList = userDao.selectList(userDomainQueryWrapper); // 位置1
PageHelper.startPage(pageNum, pageSize); // 位置2

java 复制代码
        int pageNum = userVO.getPageNum();
        int pageSize = userVO.getPageSize();
        String userName = userVO.getUserName();
        QueryWrapper<UserDomain> userDomainQueryWrapper = new QueryWrapper<>();
        userDomainQueryWrapper.likeRight("user_name", userName);
        List<UserDomain> userDomainList = userDao.selectList(userDomainQueryWrapper); // 位置1
        PageInfo<UserDomain> userDomainPageInfo = new PageInfo<>(userDomainList);
        PageHelper.startPage(pageNum, pageSize); // 位置2
        return userDomainPageInfo;

返回结果有疑问:返回的是没有分页,只要是张开头的数据都返回了。

java 复制代码
{
  "msg": "操作成功",
  "code": 200,
  "data": {
    "total": 3,
    "list": [
      {
        "id": 1,
        "userName": "张1",
        "birthday": "2023-08-09T16:00:00.000+00:00",
        "sex": "男",
        "address": "123@163.com"
      },
      {
        "id": 3,
        "userName": "张2",
        "birthday": "2023-08-09T16:00:00.000+00:00",
        "sex": "女",
        "address": "999@163.com"
      },
      {
        "id": 4,
        "userName": "张3",
        "birthday": "2023-08-09T16:00:00.000+00:00",
        "sex": "男",
        "address": "9994@qq.com"
      }
    ],
    "pageNum": 1,
    "pageSize": 4,
    "size": 3,
    "startRow": 1,
    "endRow": 3,
    "pages": 1,
    "prePage": 0,
    "nextPage": 0,
    "isFirstPage": true,
    "isLastPage": true,
    "hasPreviousPage": false,
    "hasNextPage": false,
    "navigatePages": 8,
    "navigatepageNums": [
      1
    ],
    "navigateFirstPage": 1,
    "navigateLastPage": 1
  }
}

3 案例说明

3.1 配置信息

添加依赖

xml 复制代码
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.0</version>
        </dependency>

yml配置信息

yml 复制代码
pagehelper:
  reasonable: true
  support-methods-arguments: true
  params: countSql
  helperDialect: mysql

3.2 请求体

PageInfo这个api是Pagehelper原生的对象,涵盖基本分页信息

java 复制代码
package com.geekmice.sbpagehelper.dto;

import com.github.pagehelper.PageInfo;
import lombok.Data;

/**
 * @BelongsProject: spring-boot-scaffold
 * @BelongsPackage: com.geekmice.sbpagehelper.dto
 * @Author: pingmingbo
 * @CreateTime: 2023-08-05  16:00
 * @Description: TODO
 * @Version: 1.0
 */
@Data
public class QueryDTO extends PageInfo {
    private String teacherName;
}

3.3 控制层

java 复制代码
/**
 * (Teacher)表控制层
 *
 * @author pingmingbo
 * @since 2023-08-05 15:19:26
 */
@RestController
@RequestMapping("teacher")
@Api(tags = "0.分页查询模块")
public class TeacherController {
    /**
     * 服务对象
     */
    @Resource
    private TeacherService teacherService;

    /**
     * @param queryDTO 请求体
     * @return 响应信息
     * @description 多参数分页查询
     */
    @GetMapping(value = "queryPageByDTO")
    @ApiOperation(value = "多参数分页查询")
    public AjaxResult queryPageByDTO(QueryDTO queryDTO) {
        PageInfo<Teacher> result = teacherService.queryPage(queryDTO);
        return AjaxResult.success(result);
    }
}

3.5 业务层

java 复制代码
package com.geekmice.sbpagehelper.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.geekmice.sbpagehelper.domain.Teacher;
import com.geekmice.sbpagehelper.dto.QueryDTO;
import com.github.pagehelper.PageInfo;

import java.util.List;

/**
 * (Teacher)表服务接口
 *
 * @author pingmingbo
 * @since 2023-08-05 15:19:26
 */
public interface TeacherService extends IService<Teacher> {

    /**
     * @param queryDTO 请求体
     * @return 响应信息
     * @description 多参数分页查询
     */
    PageInfo<Teacher> queryPage(QueryDTO queryDTO);
}

4.6 业务层实现类

java 复制代码
package com.geekmice.sbpagehelper.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geekmice.sbpagehelper.dao.TeacherDao;
import com.geekmice.sbpagehelper.domain.Teacher;
import com.geekmice.sbpagehelper.dto.QueryDTO;
import com.geekmice.sbpagehelper.service.TeacherService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (Teacher)表服务实现类
 *
 * @author pingmingbo
 * @since 2023-08-05 15:19:26
 */
@Service("teacherService")
@Slf4j
public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> implements TeacherService {
    @Resource
    private TeacherDao teacherDao;

    /**
     * @param queryDTO 请求体
     * @return 响应信息
     * @description 多参数分页查询
     */
    @Override
    public PageInfo<Teacher> queryPage(QueryDTO queryDTO) {
        int pageNum = queryDTO.getPageNum();
        int pageSize = queryDTO.getPageSize();
        QueryWrapper<Teacher> teacherQueryWrapper = new QueryWrapper<>();
        teacherQueryWrapper.eq("teacher_name", queryDTO.getTeacherName());
        PageHelper.startPage(pageNum,pageSize);
        List<Teacher> teacherList = teacherDao.selectList(teacherQueryWrapper);
        PageInfo<Teacher> result = new PageInfo<>(teacherList );
        return result;
    }
}

再次说明 PageHelper.startPage(pageNum,pageSize);使用顺序

4 关键问题:查询和录入操作使用一个dto出现强制分页情况【待定,问题未能复现,请稍等】

相关推荐
也无晴也无风雨27 分钟前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
2401_857610034 小时前
多维视角下的知识管理:Spring Boot应用
java·spring boot·后端
代码小鑫4 小时前
A027-基于Spring Boot的农事管理系统
java·开发语言·数据库·spring boot·后端·毕业设计
颜淡慕潇5 小时前
【K8S问题系列 | 9】如何监控集群CPU使用率并设置告警?
后端·云原生·容器·kubernetes·问题解决
CoderJia程序员甲5 小时前
重学SpringBoot3-整合 Elasticsearch 8.x (三)使用Repository
java·大数据·spring boot·elasticsearch
荆州克莱5 小时前
Mysql学习笔记(一):Mysql的架构
spring boot·spring·spring cloud·css3·技术
独泪了无痕6 小时前
WebStorm 如何调试 Vue 项目
后端·webstorm
怒放吧德德7 小时前
JUC从实战到源码:JMM总得认识一下吧
java·jvm·后端
代码小鑫7 小时前
A025-基于SpringBoot的售楼管理系统的设计与实现
java·开发语言·spring boot·后端·毕业设计
前端SkyRain7 小时前
后端SpringBoot学习项目-项目基础搭建
spring boot·后端·学习