springboot实战(19)(条件分页查询、PageHelper、MYBATIS动态SQL、mapper映射配置文件、自定义类封装分页查询数据集)

引言

  • 该类博客的学习是基于b站黑马视频springboot+vue视频学习!
  • 具体围绕项目------"大事件"进行实战学习。
    目录

一、功能介绍(需求)。

1、文章列表功能基本介绍。

2、条件分页查询功能与注意。

3、前端页面效果。(后面实现)

二、接口文档。

(1)请求路径、请求方式、接口描述。

(2)请求参数。

(3)queryString请求参数格式。

(4)响应数据。

三、实现思路分析。

(1)自定义类。(封装分页查询的结果)

(2)controller层。

(3)Service层。

(4)Mapper层。

四、具体代码书写。

(1)PageBean类。

(2)ArticleController。

(3)ArticleService接口。

(4)ArticleServiceImpl实现类。

1、mybatis的"PageHelper"开启分页查询。

2、service层实现类具体代码。(重要)

(5)Mapper层。

1、使用mapper映射配置文件。书写动态SQL语句。

2、基本的框架搭建。

3、书写SQL语句。

4、mapper层接口。

5、mapper映射配置文件。

五、后端接口测试。(postman)

(1)数据库添加并存在4条文章数据。

(2)测试条件1。

(3)测试条件2。

(4)测试条件3。

(5)测试条件4。


一、功能介绍(需求)。
1、文章列表功能基本介绍。
  • 文章列表查询功能:是用户点击左侧菜单栏的"文章管理"后。需要在当前页面的主区域展示当前用户所创建的文章信息。并且信息是以列表的形式展示。

2、条件分页查询功能与注意。
  • 列表的上方有"输入框"。用户可以根据文章的分类或者文章的发布状态去查询文章。
  • 列表的底部有"分页条"。展示了文章的总记录数,有"分页条"。用户可以选择每一页所展示的文章条数以及要查询的页码等等。

  • 注意:当用户点击了"搜索"、"上一页、下一页"、"显示每页条数"等等都需要访问后台的接口,查询满足当前条件的数据,最终在列表中进行显示文字信息。

3、前端页面效果。(后面实现)
二、接口文档。
(1)请求路径、请求方式、接口描述。
  • 路径:article。
  • 请求方式:get请求。

(2)请求参数。
  • 分页参数:"pageNum(当前页码)"、"pageSize(每页条数)"这两个参数是必须要传递的。
  • 搜索条件:"categoryId(文章分类id)"、"state":非必须传递。因为搜索的条件用户可以使用,也可以不使用。

(3)queryString请求参数格式。
  • 键值对:查询字符串由一系列键值对组成,每对键值之间用等号(=)连接。例如key=value。

  • 参数分隔:不同的键值对之间用和号(&)分隔。例如:key1=value1&key2=value2。

  • 可选性:查询字符串是可选的,不是所有的URL都需要包含查询字符串。

  • 位置:查询字符串通常位于URL的路径部分之后,以问号()开始。

  • 这里的请求参数示例如下:
  • pageNum=1&pageSize=3&categoryId=2&state=草稿

(4)响应数据。
  • 格式:JSON格式。

  • data:对应的类型是object。其中里面有两个内容。

  • "total"对应的是总条数。
  • "items"对应的是当前页的数据集合。其中它是一个数组。数组里面有多个对象。且每一个对象都是一个文章详情。
三、实现思路分析。
(1)自定义类。(封装分页查询的结果)
  • 通常。实现分页查询的时候,会提供一个自定义类用于封装查询后的结果。
  • 里面至少包括两个属性:"tota(总条数)"、"items(List<...所需数据类...>)"。
  • 到时候后台操作完,将查询后的数据封装到这个类的对象中,再返回回去即可。

(2)controller层。
  • list()方法。

  • 方法参数:"pageNum"、"pageSize"分别是当前页码与每页条数。

  • 而"categoryId"与"state"是非必须传递参数。
  • 使用注解@RequestParam(required="false")告诉MVC框架该参数不是必须的!否则前端没有这两个参数,就不允许访问该接口。
(3)Service层。
  • 首先在Service层需要定义一个前面创建的类的对象用来封装查询回的数据。
  • 这里再开启分页查询------借助于mybatis提供的"PageHelper"即可!
  • 然后再调用mapper层方法完成查询。

(4)Mapper层。
  • 因为这里的某些参数不一定会传值。
  • 所以不能把SQL语句写死!使用MYBATIS的动态SQL才行。
  • 所以要去创建mapper映射配置文件(.xml)会比较方便
四、具体代码书写。
(1)PageBean类。
  • 封装查询后的数据的实体类。

    package com.feisi.pojo;

    import lombok.AllArgsConstructor;

    import lombok.Data;

    import lombok.NoArgsConstructor;

    import java.util.List;

    //分页返回结果对象

    @Data

    @NoArgsConstructor

    @AllArgsConstructor

    public class PageBean {

    private Long total;//总条数

    private List items;//当前页数据集合

    }

(2)ArticleController。
复制代码
/**
     * 获取文章列表(条件分页列表查询)
     * @param pageNum
     * @param pageSize
     * @param categoryId
     * @param state
     * @return
     */
    @GetMapping
    public Result<PageBean<Article>> list(
            Integer pageNum,
            Integer pageSize,
            @RequestParam(required = false) Integer categoryId,
            @RequestParam(required = false) String state
    ){
        //调用service层
        PageBean<Article> pageBean = articleService.list(pageNum, pageSize, categoryId, state);
        return Result.success(pageBean);
    }
(3)ArticleService接口。
复制代码
/**
     * 条件分页列表查询
     * @param pageNum
     * @param pageSize
     * @param categoryId
     * @param state
     * @return
     */
    PageBean<Article> list(Integer pageNum, Integer pageSize, Integer categoryId, String state);
(4)ArticleServiceImpl实现类。
1、mybatis的"PageHelper"开启分页查询。
  • 导入对应的坐标。回到pom.xml文件。

  • 记得刷新Maven。

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

  • 使用指定方法PageHelper.startPage(pageNum,pageSize)。

  • pageNum:当前页码,从1开始。

  • pageSize:每页显示的记录数。

  • 调用这个方法后,PageHelper 会将分页参数保存到 ThreadLocal 中,之后执行的第一个 MyBatis 查询将会应用这些分页参数。所以需要在任何 MyBatis 查询方法调用之前调用 startPage()方法。

  • PageHelper 会自动处理 SQL 的分页逻辑,不需要再手动编写分页的 SQL 语句。

2、service层实现类具体代码。(重要)
  • 调用mapper层的list()方法进行查询时。
  • 就不需要传递"pageNum"、"pageSize"两个参数。
  • PageHelper的**startPage(pageNum,pageSize)**方法会自动在执行sql的语句后添加limit进行分页查询。

  • 注意还需要传递参数:当前已登录用户的id。(因为用户只能操作自己的)
  • userId从ThreadLocal当中获取!
  • 再通过"三个参数"的值传回去。用一个List<>集合接收查询的结果。

  • 注意:因为Page对象中提供了方法。可以获取PageHelper分页查询后得到的总记录条数和当前页数据。
  • 分页查询最终返回的就是一个Page对象。所以需要将List<>集合强转成Page对象。Page对象是List的一个实现类。属于向下转型:(Page)List<>...

  • 再通过把两个响应数据:"total"、"items"设置好,通过page对象.getTotal()、page对象.getResult()。再把对应响应给前端回去。
复制代码
@Override
    public PageBean<Article> list(Integer pageNum, Integer pageSize, Integer categoryId, String state) {
        //1.创建PageBean对象
        PageBean<Article> pageBean = new PageBean<>();
        //2.开启分页查询(PageHelper)
        //mybatis插件
        PageHelper.startPage(pageNum,pageSize);
        //3.调用mapper层方法
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("id");
        //返回的是一个List集合。查询的结果。
        List<Article> items = articleMapper.list(userId,categoryId,state);
        //Page对象中提供了方法。可以获取PageHelper分页查询后得到的总记录条数和当前页数据
        Page<Article> p = (Page<Article>) items;
        //4.设置PageBean对象属性
        pageBean.setTotal(p.getTotal());
        pageBean.setItems(p.getResult()); //当前页数据的集合
        return pageBean; //返回PageBean对象。对象中封装了分页查询后的结果。(总记录数、当前页数据)
    }
(5)Mapper层。
1、使用mapper映射配置文件。书写动态SQL语句。
  • 如果使用注解@Select(...)就会很麻烦。因为参数不一定,使用注解写动态sql很麻烦!

  • 所以在resources目录下新建与mapper层相同层级的配置文件。

  • 新建mapper映射配置文件。

  • 注意每个包是"/"(斜杠)分隔。


2、基本的框架搭建。
  • 提供映射配置文件。直接使用模板(可以网上查)

  • 映射配置文件必须要和mapper层接口所在同一个目录下!
  • 同时映射配置文件名必须与mapper层接口名一致!


  • 注意属性:namespace的值必须是对应mapper层接口的全类名!




3、书写SQL语句。

  • 注意因为参数条件不定!所以条件查询(参数):使用标签。
  • 当然如果没有条件,就不用去加标签。

  • 判断条件:标签。
  • 标签有一个属性"test"。
  • 作用就是判断该参数是否为空!不为空就去根据当前参数条件去查询。
  • 因为"categoryId(文章分类)"、"state(文章状态)"参数不一定会传过来!所以要非空校验。

  • 注意:test里面的参数名要与mapper层接口方法list()对应的参数一致!

4、mapper层接口。
复制代码
List<Article> list(Integer userId, Integer categoryId, String state);
5、mapper映射配置文件。
复制代码
<?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.feisi.mapper.ArticleMapper">
    <!--动态sql-->
    <!--id:方法名:list-->
    <!--resultType:多条数据对应的实体类类型:Article类对象-->
    <!--userId不要校验:因为没有登录就不能进行这些查询操作-->
    <select id="list" resultType="com.feisi.pojo.Article">
        select * from article
        <where>
            <if test="categoryId != null">
                category_id=#{categoryId}
            </if>
            <if test="state != null">
                and state=#{state}
            </if>
            and create_user=#{userId}
        </where>
    </select>
</mapper>
五、后端接口测试。(postman)
(1)数据库添加并存在4条文章数据。
  • 使用添加文章接口。
  • 使用添加文章接口。
  • 数据库表数据。
(2)测试条件1。
  • 文章类型与状态不传值。
  • pageSize=3:每页条数为3。pageNum=1:第一页。
(3)测试条件2。
  • 文章类型与状态不传值。
  • pageSize=3:每页条数为3。pageNum=2:第二页。
(4)测试条件3。
(5)测试条件4。
相关推荐
武昌库里写JAVA2 小时前
iview Switch Tabs TabPane 使用提示Maximum call stack size exceeded堆栈溢出
java·开发语言·spring boot·学习·课程设计
云之兕2 小时前
MyBatis 的动态 SQL
数据库·sql·mybatis
小白杨树树2 小时前
【WebSocket】SpringBoot项目中使用WebSocket
spring boot·websocket·网络协议
圈圈编码5 小时前
悲观锁和乐观锁
java·开发语言·sql·mysql
clk66078 小时前
Spring Boot
java·spring boot·后端
爱敲代码的TOM9 小时前
基于JWT+SpringSecurity整合一个单点认证授权机制
spring boot
qq_408413399 小时前
spark 执行 hive sql数据丢失
hive·sql·spark
loser.loser9 小时前
QQ邮箱发送验证码(Springboot)
java·spring boot·mybatis
喜欢踢足球的老罗9 小时前
在Spring Boot 3.3中使用Druid数据源及其监控功能
java·spring boot·后端·druid