第二十一节 SpringBoot实现分页查询

亮子 2021-05-11 14:09:58 16718 0 0 0

数据库的分页查询功能是一个后端程序员的必备技能,那么我们这一节就来说说在SpringBoot项目中如何来实现数据库查询的分页。

1、Mybatis分页

1)、添加依赖

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

也可以在创建工程的时候,通过选择添加以来,如下图:

图片alt

2)、配置数据库信息

spring.application.name=demo-mybatis-page
server.port=8000

## Mybatis
spring.datasource.url=jdbc:mysql://localhost:3306/db_test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
mybatis.typeAliasesPackage=com.shenmazong.demomybatispage.mapper
mybatis.mapperLocations=classpath:/mapper/*.xml
logging.level.com.shenmazong.demomybatispage.mapper=debug

3)、创建表tb_student

-- ----------------------------
-- Table structure for tb_student
-- ----------------------------
DROP TABLE IF EXISTS `tb_student`;
CREATE TABLE `tb_student`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学生ID',
  `student_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '学生名字',
  `age` int(11) NULL DEFAULT 0 COMMENT '学生年龄',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_student
-- ----------------------------
INSERT INTO `tb_student` VALUES (1, '吕布', 13);
INSERT INTO `tb_student` VALUES (2, '赵云', 23);
INSERT INTO `tb_student` VALUES (3, '典韦', 25);
INSERT INTO `tb_student` VALUES (4, '黄盖', 35);
INSERT INTO `tb_student` VALUES (5, '马超', 26);
INSERT INTO `tb_student` VALUES (6, '张飞', 33);

4)、定义pojo

package com.shenmazong.demomybatispage.pojo;

import lombok.Data;

@Data
public class TbStudent {
    private Integer id;
    private String studentName;
    private Integer age;
}

5)、定义mapper映射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.shenmazong.demomybatispage.mapper.TbStudentMapper">
    <select id="getStudentCount" resultType="java.lang.Integer">
        select count(id) from tb_student
    </select>

    <select id="getStudentPage" resultType="com.shenmazong.demomybatispage.pojo.TbStudent">
        select * from tb_student limit #{start},#{num}
    </select>
</mapper>

6)、定义mapper接口

package com.shenmazong.demomybatispage.mapper;

import com.shenmazong.demomybatispage.pojo.TbStudent;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface TbStudentMapper {
    Integer getStudentCount();
    List<TbStudent> getStudentPage(@Param("start") Integer start,
                                   @Param("num") Integer num);
}

7)、定义接口

package com.shenmazong.demomybatispage.controller;

import com.shenmazong.demomybatispage.mapper.TbStudentMapper;
import com.shenmazong.demomybatispage.pojo.TbStudent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class IndexController {

    @Autowired
    TbStudentMapper tbStudentMapper;

    @GetMapping(value = "/page/{page}/{num}")
    public Object getStudentByPage(@PathVariable("page") Integer page,
                                   @PathVariable("num") Integer num) {
        //--1 获取记录总数
        Integer count = tbStudentMapper.getStudentCount();

        //--2 计算记录集偏移量
        Integer start = num * (page-1);

        //--3 获取记录列表
        List<TbStudent> students = tbStudentMapper.getStudentPage(start, num);

        return students;
    }
}

2、Mybatis-Plus分页

1)、添加依赖

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.2</version>
        </dependency>

2)、准备工作

数据表、数据库连接配置、pojo对象和mybatis步骤一样,不再细说了。

3)、添加分页配置类

//Spring boot方式
@Configuration
@MapperScan("com.baomidou.cloud.service.*.mapper*")
public class MybatisPlusConfig {

    // 旧版
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }

    // 最新版
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }

}

上面的代码来源于Mybatis官网的示例,新版和旧版使用其一即可,咱们用的MP版本是3.1.2,属于旧版了,所以咱们只能用旧版的代码,具体如下:

package com.shenmazong.demomybatispage.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.shenmazong.demomybatispage.mapper.*")
public class MybatisPlusConfig {

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

4)、mapper的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.shenmazong.demomybatispage.mapper.TbStudentMapper">
    <select id="getStudentCount" resultType="java.lang.Integer">
        select count(id) from tb_student
    </select>

    <select id="getStudentPage" resultType="com.shenmazong.demomybatispage.pojo.TbStudent">
        select * from tb_student limit #{start},#{num}
    </select>

    <select id="selectPageVo" resultType="com.shenmazong.demomybatispage.pojo.TbStudent">
        select * from tb_student where age>#{age}
    </select>
</mapper>

5)、mapper接口文件

package com.shenmazong.demomybatispage.mapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shenmazong.demomybatispage.pojo.TbStudent;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface TbStudentMapper {
    Integer getStudentCount();
    List<TbStudent> getStudentPage(@Param("start") Integer start,
                                   @Param("num") Integer num);

    IPage<TbStudent> selectPageVo(Page<?> page, Integer age);
}

6)、接口controller定义

package com.shenmazong.demomybatispage.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shenmazong.demomybatispage.mapper.TbStudentMapper;
import com.shenmazong.demomybatispage.pojo.TbStudent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class IndexController {

    @Autowired
    TbStudentMapper tbStudentMapper;

    @GetMapping(value = "/page/{page}/{num}")
    public Object getStudentByPage(@PathVariable("page") Integer page,
                                   @PathVariable("num") Integer num) {
        //--1 获取记录总数
        Integer count = tbStudentMapper.getStudentCount();

        //--2 计算记录集偏移量
        Integer start = num * (page-1);

        //--3 获取记录列表
        List<TbStudent> students = tbStudentMapper.getStudentPage(start, num);

        return students;
    }

    @GetMapping(value = "/p/{page}/{num}")
    public Object getStudents(@PathVariable("page") Integer page,
                              @PathVariable("num") Integer num) {
        Page pg = new Page(page, num);

        IPage<TbStudent> tbStudentIPage = tbStudentMapper.selectPageVo(pg, 0);
        return tbStudentIPage;
    }
}

7)、运行结果如下:

图片alt

8)、总结

  • 必须要添加配置类,否则无法实现分页
  • 分页的参数必须在mapper接口函数中作为第一个参数,否则分页不起作用