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

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

一、功能需求

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

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

1.1 接口设计

Swagger2如下:

请求参数如下:

 响应如下:

二、代码实现

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

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

 在ArticleController中:

@RestController
@RequestMapping("/article")
public class ArticleController {@Autowiredprivate 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 {@Autowiredprivate CategoryService categoryService;@Overridepublic 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();//查询categoryNamearticles.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  {@TableIdprivate Long id;//标题private String title;//文章内容private String content;//文章摘要private String summary;//所属分类idprivate 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();//实现属性copyBeanUtils.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,那么就会报错。

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

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

相关文章

[计算机网络]---序列化和反序列化

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、再谈协议…

【NLP】MHA、MQA、GQA机制的区别

Note LLama2的注意力机制使用了GQA。三种机制的图如下&#xff1a; MHA机制&#xff08;Multi-head Attention&#xff09; MHA&#xff08;Multi-head Attention&#xff09;是标准的多头注意力机制&#xff0c;包含h个Query、Key 和 Value 矩阵。所有注意力头的 Key 和 V…

springboot189基于SpringBoot电商平台的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

安全基础~通用漏洞5

文章目录 知识补充CSRFSSRFxss与csrf结合创建管理员账号 知识补充 NAT&#xff1a;网络地址转换&#xff0c;可以将IP数据报文头中的IP地址转换为另一个IP地址&#xff0c;并通过转换端口号达到地址重用的目的。即通过将一个外部IP地址和端口映射更大的内部IP地址集来转换IP地…

ICLR 2023#Learning to Compose Soft Prompts for Compositional Zero-Shot Learning

组合零样本学习&#xff08;CZSL&#xff09;中Soft Prompt相关工作汇总&#xff08;一&#xff09; 文章目录 组合零样本学习&#xff08;CZSL&#xff09;中Soft Prompt相关工作汇总&#xff08;一&#xff09;ICLR 2023#Learning to Compose Soft Prompts for Compositional…

透光卓越,光耦继电器的独特特点全面解析

光耦继电器作为电子控制系统中的核心元件&#xff0c;其光电隔离技术为其独特之处。通过光电隔离技术&#xff0c;光耦继电器实现了输入和输出之间的电气隔离&#xff0c;有效阻止了高电压与低电压之间的直接接触。这项技术不仅提高了系统的安全性&#xff0c;还有效减少了电气…

Vue练习1:组件开发1(头像组件)

样式预览 注释代码 <template><div class"img-box":style"{ //动态style必须为对象width: size rem,height: size rem}"><imgclass"avatar-img":src"url" //动态url/></div> </templ…

【DDD】学习笔记-聚合设计原则

聚合设计原则 对比对象图和聚合&#xff0c;我们认为引入聚合的目的是控制对象之间的关系&#xff0c;这实则是引入聚合的技术原因。领域驱动设计引入聚合&#xff08;Aggregate&#xff09;来划分对象之间的边界&#xff0c;在边界内保证所有对象的一致性&#xff0c;并在对象…

C语言从零实现贪吃蛇小游戏

制作不易&#xff0c;点赞关注一下呗&#xff01;&#xff01;&#xff01; 文章目录 前言一. 技术要点二、WIN32API介绍三、贪吃蛇游戏设计与分析 1.游戏开始前的初始化 2.游戏运行的逻辑 总结 前言 当我们掌握链表这样的数据结构之后&#xff0c;我们就可以用它来…

比特币 P2PKH、P2SH

标准脚本P2PKH、P2SH 区块链重要基础知识7-1——标准脚本P2PKH、P2SH-CSDN博客 比特币中P2SH(pay-to-script-hash)多重签名的锁定脚本和解锁脚本 https://www.cnblogs.com/itlgl/p/10419325.html

京东护网面试题汇总

1 、JNI 函数在 java 中函数名为 com.didi.security.main,C 中的函数名是什么样的&#xff1f; com_didi_security_mian java.com.didi.security.main 2 、Frida 和 Xposed 框架&#xff1f; 3 、SSRF 利用方式&#xff1f; 4 、宏病毒&#xff1f; 5 、APP 加壳&a…

黑群晖一键修复:root、AME、DTS、转码、CPU型号等

食用方法&#xff1a;SSH连接群晖使用临时root权限执行 AME3.x激活补丁 只适用于x86_64的&#xff1a;DSM7.x Advanced Media Extensions (AME)版本3.0.1-2004、3.1.0-3005 激活过程需要下载官方的解码包&#xff0c;过程较慢&#xff0c;耐心等待。。。 DSM7.1和7.2的AME版…

Rust - 变量与数据的交互方式(move)

变量与数据的交互方式 - 移动 Rust 中的多个变量可以采用一种比较独特的方式和同一个数据进行交互&#xff0c;如下代码所示&#xff0c;将变量x的值赋给y&#xff1a; fn main() {let x 1;let y x; }我们大概可以推论出上述代码的原理&#xff1a;将1这个整数绑定给x变量&…

建造者模式-Builder Pattern

原文地址:https://jaune162.blog/design-pattern/builder-pattern/ 引言 现在一般大型的业务系统中的消息通知的形式都会有多种,比如短信、站内信、钉钉通知、邮箱等形式。虽然信息内容相同,但是展现形式缺不同。如短信使用的是纯文本的形式,钉钉使用的一般是Markdown的形…

JavaScript设计模式与开发实战

JavaScript设计模式与开发实践 第一章、面向对象的JavaScript 1.1 多态 类似java面向对象&#xff0c;通过继承共有特征&#xff0c;来实现不同方法。JavaScript的多态就是把“做什么”和“谁去做”分离&#xff0c;消除类型间的耦合关系。 他的作用就是把过程化的条件分支…

智能传感器阅读笔记-物联网用智能传感器技术的发展重点

物联网用智能传感器技术的发展重点包含边缘计算算法优化、身份认证算法优化和能量采集技术。 图1 物联网用智能传感器技术的发展重点 边缘计算算法优化 边缘计算是指在靠近物或数据源头的一侧&#xff08;传感器侧&#xff09;&#xff0c;采用集检测、计算、存储、通信功能…

电容充电速度

对电容充电的过程中&#xff0c;电容器充电的电压为&#xff0c;求电容器的充电速度。

人工智能学习与实训笔记(三):神经网络之目标检测问题

目录 五、目标检测问题 5.1 目标检测基础概念 5.1.1 边界框&#xff08;bounding box&#xff09; 5.1.2 锚框&#xff08;Anchor box&#xff09; 5.1.3 交并比 5.2 单阶段目标检测模型YOLOv3 5.2.1 YOLOv3模型设计思想 5.2.2 YOLOv3模型训练过程 5.2.3 如何建立输出…

【Windows】删除 VHD 虚拟磁盘时提示“文件已在 System 中打开”的解决方法

一、原因 正如显示的那样&#xff0c;虚拟磁盘仍在被系统占用。因此我们需要断开磁盘与系统的连接。 二、解决方法 1. 在“开始”菜单中搜索“磁盘管理”&#xff0c;选择“创建并格式化硬盘分区”。 2. 右键点击需要删除的虚拟磁盘&#xff0c;选择“分离 VHD”。 3. 点击“…

只出现一次的数字

简单 相关标签 相关企业 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题&#xff0c;且该算法只使用常量额外空间。 要设计一个…