多表联合分页查询(二)---- springboot整合MybatisPlus分页代码

目录

  • 一、分页配置代码解读(使用MP自带分页)
  • 二、Controller层代码解读
  • 三、service层代码解读
  • 四、Mapper层代码解读
  • 五、结果展示

一、分页配置代码解读(使用MP自带分页)

package com.minster.yanapi.Config;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}
  1. package com.minster.yanapi.Config;: 声明该Java类所属的包。

  2. import com.baomidou.mybatisplus.annotation.DbType;: 导入 DbType 类,该类是 MyBatis-Plus 中用于表示数据库类型的枚举类。

  3. import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;: 导入 MybatisPlusInterceptor 类,这是 MyBatis-Plus 提供的拦截器类,用于配置各种插件。

  4. import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;: 导入 PaginationInnerInterceptor 类,这是 MyBatis-Plus 提供的分页插件。

  5. import org.springframework.context.annotation.Bean;: 导入 Spring 框架的 @Bean 注解,用于将方法返回的对象注册为 Spring 容器中的 Bean。

  6. import org.springframework.context.annotation.Configuration;: 导入 Spring 框架的 @Configuration 注解,表明这是一个配置类。

  7. @Configuration: 声明这是一个配置类,用于定义配置信息。

  8. public class MybatisPlusConfig {: 定义名为 MybatisPlusConfig 的类。

  9. @Bean: 注解在方法上,表示该方法返回的对象将被注册为一个 Bean。

  10. public MybatisPlusInterceptor mybatisPlusInterceptor() {: 定义一个名为 mybatisPlusInterceptor 的方法,返回一个 MybatisPlusInterceptor 对象。

  11. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();: 创建一个 MybatisPlusInterceptor 对象。

  12. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));: 向拦截器中添加一个内部拦截器,这里添加了一个用于支持MySQL数据库的分页插件。

  13. return interceptor;: 返回配置好的拦截器对象。

二、Controller层代码解读

 @GetMapping()public ApiResponse<Page<ArticleResp>> getArticleList(@RequestParam("current") Integer current,@RequestParam("pageSize") Integer pageSize) {Page<Map<String, Object>> page = new Page<>(current, pageSize);return yanArticleService.getArticleList(page);}
  • @GetMapping() 注解表示这个方法处理 HTTP GET 请求,并且没有指定具体的路径,即映射到当前路径。这说明该方法应该处理类似于 http://example.com/your-controller-path 这样的请求。

  • public ApiResponse<Page<ArticleResp>> 是方法的返回类型。这个方法返回一个包含 ApiResponse 对象的泛型,而 ApiResponse 的泛型参数是 Page<ArticleResp>,表示返回的数据是分页的文章列表。

  • @RequestParam("current") Integer current@RequestParam("pageSize") Integer pageSize 是用来接收请求中的参数的。current 参数用于指定当前页码,pageSize 参数用于指定每页的条目数量。这两个参数会被Spring自动从请求中获取并传递给方法。

  • Page<Map<String, Object>> page = new Page<>(current, pageSize); 创建了一个 Page 对象,该对象用于表示分页信息,其中 current 是当前页码,pageSize 是每页的条目数量。这里使用了一个泛型为 Map<String, Object>Page 类型。

  • yanArticleService.getArticleList(page); 调用了一个名为 yanArticleService 的服务(Service)的 getArticleList 方法,并传递了前面创建的 Page 对象作为参数。这个方法似乎返回一个 ApiResponse 对象,其中包含了一个分页的文章列表。

三、service层代码解读

 public ApiResponse<Page<ArticleResp>> getArticleList(Page<Map<String, Object>> page) {Page<Map<String, Object>> result = yanArticleMapper.getArticleList(page);// 将查询结果转换为 Page<YanArticle>List<ArticleResp> yanArticles = result.getRecords().stream().map(record -> {ArticleResp articleResp = new ArticleResp();articleResp.setId((Long) record.get("id"));articleResp.setTitle((String) record.get("title"));articleResp.setSummary((String) record.get("summary"));articleResp.setCreateTime((Date) record.get("createTime"));articleResp.setUsername((String) record.get("username"));articleResp.setAvatar((String) record.get("avatar"));articleResp.setLikeCount((Long) record.get("likeCount"));articleResp.setCommentCount((Long) record.get("commentCount"));return articleResp;}).collect(Collectors.toList());Page<ArticleResp> yanArticlePage = new Page<>();yanArticlePage.setRecords(yanArticles);yanArticlePage.setCurrent(result.getCurrent());yanArticlePage.setSize(result.getSize());yanArticlePage.setTotal(result.getTotal());yanArticlePage.setPages(result.getPages());return ApiResponse.success(yanArticlePage);}
  • 方法声明了一个返回类型为 ApiResponse<Page<ArticleResp>> 的公共方法,方法名为 getArticleList。方法接收一个 Page<Map<String, Object>> 类型的参数 page,该参数用于表示分页信息。

  • 调用了 yanArticleMappergetArticleList 方法,传递了上面接收的 page 对象作为参数。getArticleList 方法返回一个 Page<Map<String, Object>> 类型的分页结果,其中包含了从数据库中查询到的原始数据。

  • 使用Java 8+的流式处理,对从数据库中查询到的原始数据进行转换。通过 stream() 对结果集进行流式处理,使用 map 将每个原始记录转换为一个 ArticleResp 对象,最后通过 collect(Collectors.toList()) 将转换后的对象集合收集成一个列表。

  • 创建一个新的 Page<ArticleResp> 对象 yanArticlePage,并将上面转换后的文章列表设置为新对象的记录(setRecords),同时将原始分页结果中的页码、每页条目数、总条目数、总页数等信息也设置到新对象中。

  • 最后,使用 ApiResponse.success() 方法将新创建的分页结果对象 yanArticlePage 包装为成功的 ApiResponse 对象,并将其返回。这个方法的最终返回结果是一个带有文章分页信息的成功响应对象。

四、Mapper层代码解读

@Select("SELECT\n" +"    a.id,\n" +"    a.title ,\n" +"    a.summary ,\n" +"    a.create_time AS createTime,\n" +"    u.username ,\n" +"    d.avatar, \n" +"    COUNT(DISTINCT c.id) AS likeCount ,\n" +"    COUNT(DISTINCT l.id) AS commentCount\n" +"FROM\n" +"    yan_article a\n" +"JOIN\n" +"    yan_user u ON a.author_id = u.id\n" +"LEFT JOIN\n" +"    yan_details d ON u.detail_id = d.id\n" +"LEFT JOIN\n" +"    yan_comment c ON a.id = c.article_id\n" +"LEFT JOIN\n" +"    yan_like l ON a.id = l.article_id\n" +"GROUP BY\n" +"    a.id, a.title, a.summary, a.create_time, u.username, d.avatar")Page<Map<String, Object>> getArticleList(Page<Map<String, Object>> page);

SQL语句

SELECTa.id,a.title ,a.summary ,a.create_time AS createTime,u.username ,d.avatar,  -- 不使用前缀COUNT(DISTINCT c.id) AS likeCount ,COUNT(DISTINCT l.id) AS commentCount
FROMyan_article a
JOINyan_user u ON a.author_id = u.id
LEFT JOINyan_details d ON u.detail_id = d.id
LEFT JOINyan_comment c ON a.id = c.article_id
LEFT JOINyan_like l ON a.id = l.article_id
GROUP BYa.id, a.title, a.summary, a.create_time, u.username, d.avatar
  • @Select 注解表示这是一个查询语句。该语句使用了类似 SQL 的语法,用于从数据库中获取文章列表的相关信息。

  • 查询语句中使用了表别名(如 audcl)来简化表的引用。

  • 查询语句主要涉及以下表:

    • yan_article a: 文章表,用别名 a 引用。
    • yan_user u: 用户表,用别名 u 引用。
    • yan_details d: 用户详情表,用别名 d 引用。
    • yan_comment c: 评论表,用别名 c 引用。
    • yan_like l: 点赞表,用别名 l 引用。
  • 在查询语句中,使用了左连接 (LEFT JOIN) 将文章表与用户表、用户详情表、评论表、点赞表进行关联。

  • 使用 COUNT(DISTINCT c.id) 计算每篇文章的点赞数量,使用 COUNT(DISTINCT l.id) 计算每篇文章的评论数量。

  • 最后,使用 GROUP BY 对文章的相关字段进行分组,包括文章的 idtitlesummarycreate_time、作者的 username 以及作者的头像 avatar

  • 查询结果的字段包括文章的基本信息(idtitlesummarycreateTime)、作者的用户名 (username)、作者的头像 (avatar)、点赞数量 (likeCount) 以及评论数量 (commentCount)。

  • 查询结果以 Page<Map<String, Object>> 的形式返回,其中 Map<String, Object> 表示每一行数据,Page 则表示分页信息。

五、结果展示

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

matlab 三质量-弹簧系统受激振力

1、内容简介 略 44-可以交流、咨询、答疑 建立系统运动方程&#xff0c;研究固有频率和对应主振型 2、内容说明 略 三质量&#xff0d;弹簧系统受激振力&#xff0c;并不考虑各自的阻尼。建立系统运动方程。 解&#xff1a;由于阻尼对固有频率没有影响&#xff0c;故本文不…

Sora将创造多少算力需求?

1.1 Sora 训练与推理算力需求初步测算 Sora发布表现亮眼&#xff0c;TransformerDiffusion架构或成为文生视频大模型新范式。据Sora技术报告&#xff0c;类似于LLM将不同文本数据统一为token&#xff0c;Sora可将不同类型的视频和图像等视觉数据统一为patches&#xff0c;具体…

IDA使用-2023CICSN华中赛区pwn题逆向为例

文章目录 相关字节标识导入函数和导出函数找程序入口函数选项设置重命名CISCN2023华中赛区分区赛AWDIDA源码main 构造结构体sub_141B() 打开局部变量类型的视图增加变量类型重新定义变量类型再次设置变量类型并重新定义再次设置变量类型并重新定义再次设置变量类型并重新定义 设…

【数据结构与算法】(20)高级数据结构与算法设计之 Greedy Algorithm 贪心算法 代码示例与详细讲解

目录 4.2 Greedy Algorithm1) 贪心例子DijkstraPrimKruskal 2) 零钱兑换问题有几个解&#xff08;零钱兑换 II&#xff09;Leetcode 518最优解&#xff08;零钱兑换&#xff09;- 穷举法 Leetcode 322最优解&#xff08;零钱兑换&#xff09;- 贪心法 Leetcode 322 3) Huffman …

线程池的常用实现及执行流程

线程池 线程池线程池接口线程池参数线程池分类动态数目线程池固定数目线程池单例线程池任务调度线程池 线程池的执行流程 线程池 线程池接口 线程池参数 1、corePoolSize&#xff1a;核心线程数&#xff0c;线程池中最少线程&#xff0c;核心线程不会被回收。 2、maximumPoo…

6-pytorch-神经网络搭建

b站小土堆pytorch教程学习笔记 1.神经网络骨架搭建&#xff1a;Containers 官方文档代码&#xff1a; import torch.nn as nn import torch.nn.functional as Fclass Model(nn.Module):def __init__(self):super().__init__()self.conv1 nn.Conv2d(1, 20, 5)self.conv2 nn.…

nccl2安装指南

https://developer.nvidia.com/nccl/nccl-download 旧版本安装: https://developer.nvidia.com/nccl/nccl-legacy-downloads 找到你对应的CUDA版本 我这里选择 deb 文件安装了 sudo dpkg -i nccl-local-repo-ubuntu2004-2.16.5-cuda11.8_1.0-1_amd64.debsudo cp /var/nccl-lo…

深度解析:Integer.parseInt() 源码解读

深度解析&#xff1a;Integer.parseInt() 源码解读 关键要点 解析字符&#xff1a;用于将字符转换为对应的数字值 Character.digit(s.charAt(i),radix) 确定limit&#xff1a;根据正负号分别设定 int limit -Integer.MAX_VALUE;【正】 limit Integer.MIN_VALUE;【负】 负数…

车载测试面试:题库+项目

车载测试如何面试&#xff08;面试技巧&#xff09;https://blog.csdn.net/2301_79031315/article/details/136229809 入职车载测试常见面试题(附答案&#xff09;https://blog.csdn.net/2301_79031315/article/details/136229946 各大车企面试题汇总&#xff08;含答案&am…

mac下使用jadx反编译工具

直接执行步骤&#xff1a; 1.创建 jadx目录 mkdir jadx2.将存储库克隆到目录 git clone https://github.com/skylot/jadx.git 3. 进入 jadx目录 cd jadx 4.执行编译 等待片刻 ./gradlew dist出现这个就代表安装好了。 5.最后找到 jadx-gui 可执行文件&#xff0c;双击两下…

为什么TestNg会成为Java测试框架的首选?还犹豫什么,看它!

上一篇自动化测试我们大概了解了测试的目标、测试的技术选型以及搭建平台的目标及需求&#xff0c;也确定了自动化测试方案以testNg作为整个测试流程贯穿的基础支持框架&#xff0c;那么testNg究竟有什么特点&#xff1f;本篇开始我们来详细的学习testNg这个测试框架。 为什么要…

基于Android的校园请假App的研究与实现

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

java面试题之mysql篇

1、数据库索引 ​​​​​​​ 索引是对数据库表中一列或多列的值进行排序的一种结构&#xff0c;使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她&#xff0c;则与在表中搜索所有的行相比&#xff0c;索引有助于更快地获取信息。 索引的一个主要…

protobuf简单使用(二)

介绍 上一节中&#xff0c;我们介绍了protobuf&#xff0c;简单来说&#xff0c;它是一种消息数据格式&#xff0c;其作用类似于json&#xff0c;但是比json的使用效率要高。 除此以外&#xff0c;我们介绍了protobuf的简单使用&#xff0c;也就是如何可以像使用json一样&…

Springboot+vue的社区医疗综合服务平台(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的社区医疗综合服务平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的社区医疗综合服务平台&#xff0c;采用M&#xff08;m…

五、数组——Java基础篇

六、数组 1、数组元素的遍历 1.1数组的遍历&#xff1a;将数组内的元素展现出来 1、普通for遍历&#xff1a;根据下表获取数组内的元素 2、增强for遍历&#xff1a; for&#xff08;数据元素类型 变量名&#xff1a;数组名&#xff09;{ 变量名&#xff1a;数组内的每一个值…

面试经典150题【21-30】

文章目录 面试经典150题【21-30】6.Z字形变换28.找出字符串中第一个匹配项的下标68.文本左右对齐392.判断子序列167.两数之和11.盛最多水的容器15.三数之和209.长度最小的子数组3.无重复字符的最长子串30.串联所有单词的子串 面试经典150题【21-30】 6.Z字形变换 对于“LEETC…

【Java多线程】对线程池的理解并模拟实现线程池

目录 1、池 1.1、线程池 2、ThreadPoolExecutor 线程池类 3、Executors 工厂类 4、模拟实现线程池 1、池 “池”这个概念见到非常多&#xff0c;例如常量池、数据库连接池、线程池、进程池、内存池。 所谓“池”的概念就是&#xff1a;&#xff08;提高效率&#xff09; 1…

计网day5

六 传输层 6.1 传输层概述 6.2 UDP协议 6.3 TCP协议 TCP连接管理&#xff1a; TCP可靠传输&#xff1a; TCP拥塞控制&#xff1a;

[ROS 系列学习教程] rosbag 命令行介绍

ROS 系列学习教程(总目录) 本文目录 rosbag 命令行1.1 rosbag check1.2 rosbag compress1.3 rosbag decompress1.4 rosbag filter1.5 rosbag fix1.6 rosbag info1.7 rosbag play1.8 rosbag record1.9 rosbag reindex 有时我们需要将 topic 中的数据保存下来以便后面分析&#x…