Web项目利用MybatisPlus进行分页查询

之前在写博客系统前台页面的时候,遇到了利用mp进行分页查询的情况,由于涉及到的知识点相对较为重要,固写一篇博客以此巩固。

一、功能需求

在首页和分类页面都需要查询文章列表。

  • 首页:查询所有的文章
  • 分类页面:查询对应分类下的文章
  • 要求:①只能查询正式发布的文章   ②置顶的文章要显示在最前面

1.1 接口设计

Swagger2如下:

请求参数如下:

 响应如下:

二、代码实现

由于我们涉及了利用mp进行分页的情况,所以我们需要先配置mp的配置类:

@Configuration
public class MbatisPlusConfig {

    /**
     * 3.4.0之后版本
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

 在ArticleController中:

@RestController
@RequestMapping("/article")
public class ArticleController {

    @Autowired
    private ArticleService articleService;


    @GetMapping("/articleList")
    public ResponseResult articleList(Integer pageNum,Integer pageSize,Long categoryId){
        return articleService.articleList(pageNum,pageSize,categoryId);
    }

}

分析:

这里前端传来的请求参数类型是 query 类型,如果我们需要解决前端和后端中命名不一致的问题,可以使用@RequestParms注解。关于SpringMVC的相关知识可以移步博客的另一篇博客:

SpringMVC的三大功能

ArticleService中: 

在ArticleServiceImpl中: 


@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Autowired
    private CategoryService categoryService;


    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        //查询条件
        LambdaQueryWrapper<Article> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 如果 有categoryId 就要 查询时要和传入的相同
        lambdaQueryWrapper.eq(Objects.nonNull(categoryId)&&categoryId>0 ,Article::getCategoryId,categoryId);
        // 状态是正式发布的
        lambdaQueryWrapper.eq(Article::getStatus,SystemConstants.ARTICLE_STATUS_NORMAL);
        // 对isTop进行降序
        lambdaQueryWrapper.orderByDesc(Article::getIsTop);

        //分页查询
        Page<Article> page = new Page<>(pageNum,pageSize);
        page(page,lambdaQueryWrapper);

        List<Article> articles = page.getRecords();
        //查询categoryName
        articles.stream()
                .map(article -> article.setCategoryName(categoryService.getById(article.getCategoryId()).getName()))
                .collect(Collectors.toList());
        //articleId去查询articleName进行设置
//        for (Article article : articles) {
//            Category category = categoryService.getById(article.getCategoryId());
//            article.setCategoryName(category.getName());
//        }

        //封装查询结果
        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(page.getRecords(), ArticleListVo.class);

        PageVo pageVo = new PageVo(articleListVos,page.getTotal());
        return ResponseResult.okResult(pageVo);
    }
}

 分析:

这里涉及到蛮多知识点的,如VO、Bean工具类拷贝等。

我们这里重点关注data里面的数据,外部的code、data、msg为我自定义的响应类 ReponseResult。

这里其实就涉及到VO的概念,这个data里面其实可以看出来,应该是由两个部分组成,一个是rows,一个是total。

因此,我们需要创建一个PageVo的概念:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageVo {
    private List rows;
    private Long total;
}

而这个rows我们使用List集合接收,但是我们仔细观察Article类,发现它实际的字段是多于我们需要传输给前端的字段的,并且有些字段Article类是没有的,这里为了不破坏Article的耦合性,所以我们又需要创建一个ArticleListVo对象:



import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ArticleListVo {

    private Long id;
    //标题
    private String title;
    //文章摘要
    private String summary;
    //所属分类名
    private String categoryName;
    //缩略图
    private String thumbnail;
    
    //访问量
    private Long viewCount;

    private Date createTime;


}

 Article对象如下:

import java.util.Date;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * 文章表(Article)表实体类
 *
 * @author makejava
 * @since 2022-02-01 11:36:28
 */
@SuppressWarnings("serial")
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("sg_article")
@Accessors(chain = true)
public class Article  {
    @TableId
    private Long id;
    //标题
    private String title;
    //文章内容
    private String content;
    //文章摘要
    private String summary;
    //所属分类id
    private Long categoryId;

    @TableField(exist = false)
    private String categoryName;
    //缩略图
    private String thumbnail;
    //是否置顶(0否,1是)
    private String isTop;
    //状态(0已发布,1草稿)
    private String status;
    //访问量
    private Long viewCount;
    //是否允许评论 1是,0否
    private String isComment;

    @TableField(fill = FieldFill.INSERT)
    private Long createBy;
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateBy;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    //删除标志(0代表未删除,1代表已删除)
    private Integer delFlag;

    public Article(Long id, long viewCount) {
        this.id = id;
        this.viewCount = viewCount;
    }
}

细心观察可以发现,Article类虽然有大部分的ArticleListVo对象的属性,但是却缺少一个categoryName属性:

这里是因为Article表是没有这个属性的,所以我们加入这个@TableFiled注解,来避免mp在进行ORM映射的时候找不到属性而报错。

给Article类添加这个属性只是为了方便后面进行Bean拷贝而已,因为Article类必须有这个属性,才能将这个属性拷贝到我们要传输给前端的ArticleListVo属性。

可以通过for循环或者是Stream流的方式来将Article这个类的CategoryName属性填充完毕:

最后再进行Bean拷贝:

package com.fox.utils;

import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class BeanCopyUtils {


    //由于这是工具类,就直接将构造方法设置为私有的
    private BeanCopyUtils() {

    }

    public static <T> T copyBean(Object source,Class<T> clazz) {
        //创建目标对象
        T result = null;
        try {
            result = clazz.newInstance();
            //实现属性copy
            BeanUtils.copyProperties(source, result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //返回结果
        return result;
    }
    public static <E,T> List<T> copyBeanList(List<E> list, Class<T> clazz){
        List<T> result = new ArrayList<>();
        for (E e : list) {
            T t = copyBean(e, clazz);
            result.add(t);
        }
        return result;
//        return list.stream()
//                .map(E -> copyBean(E, clazz))
//                .collect(Collectors.toList());
    }
}

需要注意的是,这里在进行Bean拷贝的时候,其会根据属性名自动匹配,但是需要保证拷贝的双方属性的类型是一致的,不然会转换失败,比如 Article  类中 id属性的类型是 long,而其Vo对象的id属性为 Integer,那么就会报错。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

隐函数的求导【高数笔记】

1. 什么是隐函数&#xff1f; 2. 隐函数的做题步骤&#xff1f; 3. 隐函数中的复合函数求解法&#xff0c;与求导中复合函数求解法有什么不同&#xff1f; 4. 隐函数求导的过程中需要注意什么&#xff1f;

透光力之珠——光耦固态继电器的独特特点解析

光耦固态继电器作为现代电子控制领域中的重要组件&#xff0c;以其独特的特点在工业、通信、医疗等多个领域得到广泛应用。本文将深入剖析光耦固态继电器的特点&#xff0c;揭示其在电子控制中的卓越性能。 光耦固态继电器的光电隔离技术 光耦固态继电器以其光电隔离技术而脱颖…

深入了解社区店:定义、模式与优势

在当今的商业环境中&#xff0c;社区店正逐渐成为创业者们关注的热点。本文将以我的鲜奶吧店铺为例&#xff0c;深入探讨社区店的定义、模式和优势&#xff0c;为您提供最有价值的干货信息。 1、社区店的定义 社区店是指位于社区内或周边&#xff0c;以服务社区居民为主要目标…

Diffusion Transformer U-Net for MedicalImage Segmentation

用于医学图像分割的扩散变压器U-Net 摘要&#xff1a; 扩散模型在各种发电任务中显示出其强大的功能。在将扩散模型应用于医学图像分割时&#xff0c;存在一些需要克服的障碍:扩散过程调节所需的语义特征与噪声嵌入没有很好地对齐;这些扩散模型中使用的U-Net骨干网对上下文信…

2.15学习总结

2.15 1.聪明的质监员&#xff08;二分前缀和&#xff09; 2.村村通&#xff08;并查集&#xff09; 3.玉蟾宫(悬线法DP) 4.随机排列&#xff08;树状数组逆序对问题&#xff09; 5.增进感情&#xff08;DFS&#xff09; 6.医院设置&#xff08;floyd&#xff09; 聪明的质监员…

P1010 [NOIP1998 普及组] 幂次方题解

题目 任何一个正整数都可以用2的幂次方表示。例如137。 同时约定次方用括号来表示&#xff0c;即ab可表示为a(b)。 由此可知&#xff0c;137可表示为2(7)2(3)2(0)&#xff0c;进一步&#xff1a;72 ( 用2表示)&#xff0c;并且32。 所以137可表示为2(2(2)22(0))2(22(0))2(0…

ESP32学习(4)——电脑远程控制LED灯

1.思路梳理 首先需要让ESP32连接上WIFI 然后创建udp socket 接着接收udp数据 最后解析数据&#xff0c;控制LED 2.代码实现 import network from socket import * from machine import Pin p2Pin(2,Pin.OUT)def do_connect(): #连接wifi wlan network.WLAN(network.STA_IF)…

optee imx8mm

总仓库 git clone https://github.com/Xsyin/imx8mqevk.git -b container_region 替换imx8mqevk中的optee-client git clone https://github.com/nxp-imx/imx-optee-client.git -b lf-5.15.32_2.0.0 用 5.15.32 kernel 会有如下报错&#xff0c;需要将optee os升级到分支 lf-…

MySQL容器的数据挂载

挂载本地目录或文件 可以发现&#xff0c;数据卷的目录结构较深&#xff0c;如果我们去操作数据卷目录会不太方便。在很多情况下&#xff0c;我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似&#xff1a; # 挂载本地目录 -v 本地目录:容器内目录 # 挂载本地…

第9讲重写登录成功和登录失败处理器

重写登录成功和登录失败处理器 common下新建security包&#xff0c;再新建两个类&#xff0c;LoginSuccessHandler和LoginFailureHandler Component public class LoginSuccessHandler implements AuthenticationSuccessHandler {Overridepublic void onAuthenticationSuccess…

请标记你的龙年心愿关键词

昨天外孙陪我游了崇州市白头镇、道民镇&#xff08;竹艺村&#xff09;&#xff0c;见我心情愉悦&#xff0c;今天再陪我去饱览其他风景名胜&#xff0c;所以笔者——本“人民体验官”特别推广人民日报官方微博文化产品《2024年第一批春花开了》《#大年初七#&#xff0c;标记你…

三种输入输出函数

目录 printf函数 scanf函数 getchar函数 putchar函数 gets函数 puts函数 printf函数 当你需要将数据或文本输出到屏幕或其他输出设备时&#xff0c;C语言提供了一个非常有用的函数&#xff0c;即 printf() 函数。它是标准库中定义的函数&#xff0c;用于格式化输出。 pr…

如何监控另一台电脑屏幕画面?如何远程监控电脑屏幕?

在数字化时代&#xff0c;随着远程工作和协作的普及&#xff0c;电脑屏幕监控的需求也日益增长。无论是出于安全考虑、提高员工工作效率&#xff0c;还是确保企业机密的保密性&#xff0c;电脑屏幕监控都成为了企业不可或缺的管理工具。那么&#xff0c;如何监控另一台电脑屏幕…

怎么恢复电脑重装前的数据?介绍几种有效的方法

在日常生活和工作中&#xff0c;电脑已成为我们不可或缺的工具。然而&#xff0c;有时候我们会遇到一些突发情况&#xff0c;比如电脑系统崩溃需要重新安装系统。在这个过程中&#xff0c;我们可能会失去一些重要的数据&#xff0c;比如照片、文档、视频等。这些数据可能包含着…

第三十一回 武行者醉打孔亮 锦毛虎义释宋江-解压文件但不重复解压

武松发现蜈蚣岭寺庙里一个人搂着女的看月亮&#xff0c;就把那个人和他的道童都杀了。原来那个人叫飞天蜈蚣王道人&#xff0c;那女的是被掳来的&#xff0c;她将一包金银给武松&#xff0c;武松没有要。 就像武松在处理问题时展现出的智慧和决断力&#xff0c;现代IT技术同样…

使用骨传导耳机真的不损伤听力吗?哪些人群适合购买骨传导耳机?

如果是正确的使用骨传导耳机&#xff0c;是不会损伤听力的&#xff0c;因为骨传导耳机采用开放式佩戴&#xff0c;而且传声方式不经过耳道和耳膜&#xff0c;是通过人体骨骼来传递声音&#xff0c;不会损伤耳膜&#xff0c;所以不会损伤听力。 由于骨传导耳机的特殊性&#xff…

SG3225VEN晶体振荡器SPXO

SG3225VEN是爱普生的一款LVDS输出差分晶振&#xff0c;小体积晶振尺寸3.2*2.5mm的石英晶体振荡器&#xff0c;六脚贴片晶振&#xff0c;电源电压2.5V、3.3V&#xff0c;频率范围25mhz ~ 500mhz&#xff0c;工作温度可达到- 40℃~ 105℃&#xff0c;该产品具有超小型&#xff0…

【深入理解BEVFormer】BEVFormer

任务场景 多模态融合和多传感器融合 BEV&#xff1a;鸟瞰图 这个特征空间与每个视角都相关 早期是用后融合&#xff0c;目前比较流行的是特征级融合 自身运动补偿&#xff1a;如果按照像素点进行特征对齐&#xff0c;需要指定偏移量 x y两个方向 特征空间是自己定义的&#xf…

使用REQUESTDISPATCHER对象调用错误页面

使用REQUESTDISPATCHER对象调用错误页面 问题陈述 InfoSuper公司已经创建了一个动态网站。发生错误时,浏览器中显示的堆栈跟踪很难理解。公司的系统分析师David Wong让公司的软件程序员Don Allen创建自定义错误页面。servlet引发异常时,应使用RequestDisapatcher对象向自定义…