当前位置: 首页 > news >正文

spring同一个接口如何分页实现主表或主+联表group by查询

1 需求背景

我们的上游系统想要知道主表的记录关联子表所有记录中是否有一条满足特定的条件,如果有满足的就返回主表中的id。比如品牌brand主表中id为10的记录,在子表brand_rel中有id为1,2,3,4的这四个记录,其中1,2所在记录的status字段值满足等于0,那么就可以返回10给调用方。

其次这个查询功能是要做在原来的查询接口中的,旧接口只允许匹配针对主表的条件进行分页查询。

2 需求分析

2.1 如何兼容旧功能

通过在入参的请求体中新增一个子表的查询字段,后端拿到请求体会先判断子表的这个字段是否为空,如果为空则走旧有的查询条件,否则走新的查询分支。

2.2 联表查询,一个主表的记录会匹配到多个子表的记录,需要去重。

使用group by关键字对主表的id进行去重。

2.3 量很大时,需要分页

使用合理的分页插件。

3 实现

3.1 需求背景和分析

  1. 主表 brand 记录与子表 brand_rel 记录有一对多的关系。
  2. 新增一个子表查询字段来扩展旧接口。
  3. 使用 GROUP BY 去重主表记录。
  4. 使用分页插件实现数据的分页。

为了实现这一需求,假设我们在使用 Spring Boot 框架和 MyBatis-Plus 分页插件。

3.2 数据库表结构

-- 主表 brand
CREATE TABLE brand (id BIGINT PRIMARY KEY,name VARCHAR(100)
);-- 子表 brand_rel
CREATE TABLE brand_rel (id BIGINT PRIMARY KEY,brand_id BIGINT,status INT,FOREIGN KEY (brand_id) REFERENCES brand(id)
);

3.3 SQL 查询语句

为了得到符合条件的主表 brand ID 列表,SQL 查询如下:

SELECT b.id
FROM brand b
JOIN brand_rel br ON b.id = br.brand_id
WHERE br.status = 0
GROUP BY b.id
LIMIT #{offset}, #{pageSize};

3.4 Controller 和 Service 层实现

以下提供一个简单的 Spring Boot Controller 和 Service 实现。

3.4.1 请求体对象

public class BrandQueryRequest {private String mainTableCondition; // 主表的查询条件,可以扩展private String subTableCondition;  // 子表的查询条件,比如 "br.status = 0"private int offset;private int pageSize;// getters and setters
}

3.4.2 Controller

@RestController
@RequestMapping("/api/brands")
public class BrandController {@Autowiredprivate BrandService brandService;@PostMapping("/query")public ResponseEntity<List<Long>> queryBrands(@RequestBody BrandQueryRequest request) {List<Long> result = brandService.queryBrandIds(request);return ResponseEntity.ok(result);}
}

3.4.3 Service

@Service
public class BrandService {@Autowiredprivate BrandMapper brandMapper;public List<Long> queryBrandIds(BrandQueryRequest request) {if (request.getSubTableCondition() == null) {// 走旧查询逻辑return brandMapper.queryBrandsByMainCondition(request.getMainTableCondition(), request.getOffset(), request.getPageSize());} else {// 新的查询逻辑return brandMapper.queryBrandsBySubCondition(request.getSubTableCondition(), request.getOffset(), request.getPageSize());}}
}

3.4.4 Mapper

利用 MyBatis-Plus,定义一个自定义的 SQL 查询方法:

@Mapper
public interface BrandMapper {@Select("<script>" +"SELECT b.id " +"FROM brand b " +"<where>" +"  <if test='mainTableCondition != null'>AND ${mainTableCondition}</if> " +"</where>" +"GROUP BY b.id " +"LIMIT #{offset}, #{pageSize}" +"</script>")List<Long> queryBrandsByMainCondition(@Param("mainTableCondition") String mainTableCondition, @Param("offset") int offset, @Param("pageSize") int pageSize);@Select("<script>" +"SELECT b.id " +"FROM brand b " +"JOIN brand_rel br ON b.id = br.brand_id " +"<where>" +"  <if test='subTableCondition != null'>AND ${subTableCondition}</if> " +"</where>" +"GROUP BY b.id " +"LIMIT #{offset}, #{pageSize}" +"</script>")List<Long> queryBrandsBySubCondition(@Param("subTableCondition") String subTableCondition, @Param("offset") int offset, @Param("pageSize") int pageSize);
}

3.4.5 总结

这样,我们就成功地实现了一个能够兼容旧功能并支持新功能的查询接口。通过在请求体中新增一个子表的查询字段来扩展逻辑,确保最大限度的代码复用和功能扩展。

相关文章:

spring同一个接口如何分页实现主表或主+联表group by查询

1 需求背景 我们的上游系统想要知道主表的记录关联子表所有记录中是否有一条满足特定的条件&#xff0c;如果有满足的就返回主表中的id。比如品牌brand主表中id为10的记录&#xff0c;在子表brand_rel中有id为1&#xff0c;2&#xff0c;3&#xff0c;4的这四个记录&#xff0…...

SpringDataJpa源码分析

我们在定义Repository的时候通常定义的时一个接口&#xff0c;而并没有去实现这个接口&#xff0c;那么Jpa是如何让开发者无需自己实现接口就可以使用Repository去操作数据库&#xff1f; 动态代理&#xff01;&#xff01;&#xff01; Repository原理 试想一下JPA是如何做的…...

卷积神经网络 - 卷积神经网络与深度学习的历史篇

序言 卷积神经网络&#xff08; Convolutional Neural Networks, CNN \text{Convolutional Neural Networks, CNN} Convolutional Neural Networks, CNN&#xff09;与深度学习作为人工智能领域的两大重要分支&#xff0c;其发展历程充满了探索与突破。深度学习&#xff0c;作…...

初识 Floodfall 算法

文章目录 **一、Floodfall 算法的概述****二、深度优先搜索&#xff08;DFS&#xff09;和广度优先搜索&#xff08;BFS&#xff09;在 Floodfall 算法中的应用****三、算法的基本原理****四、应用场景** 一、Floodfall 算法的概述 Floodfall 算法通常用于解决与区域填充、图的…...

[Linux] LVM挂载的硬盘重启就掉的问题解决

问题&#xff1a;系统重启后挂在逻辑卷的盘会掉&#xff08;必现&#xff09; 环境&#xff1a;SUSE Linux 11 SP4 原因&#xff1a;boot.lvm是关闭的 解决&#xff1a;boot.lvm设置开启 参考资料&#xff1a; linux下lvm状态Not avaliable问题排查及处理(常见Suse操作系统…...

YOLOv8改进 | 主干网络 | 用EfficientNet卷积替换backbone【教程+代码 】

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录 :《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有80+篇内容,内含各种Head检测头、损失函数Loss、…...

数据库规范化设计 5大基本原则

规范化设计原则是数据库设计的基本原则&#xff0c;有助于减少数据冗余&#xff0c;提高数据一致性和完整性&#xff0c;简化数据管理&#xff0c;增强数据安全性&#xff0c;对整个开发项目至关重要。而缺乏规范化设计会导致数据冗余&#xff0c;增加存储成本&#xff0c;引发…...

【nginx】解决k8s中部署nginx转发不会自动更新域名解析启动失败的问题

文章目录 1. 问题2.解决办法3.扩展说明3.1 DNS解析阶段划分3.2 问题说明3.2.1 先看/etc/resolv.conf说明3.2.2 针对第一个问题3.2.3 针对第二个问题 【后端】NginxluaOpenResty高性能实践 参考&#xff1a; https://blog.csdn.net/u010837612/article/details/123275026 1. 问…...

LeetCode637 二叉树的层平均值

前言 题目&#xff1a; 637. 二叉树的层平均值 文档&#xff1a; 代码随想录——二叉树的层平均值 编程语言&#xff1a; C 解题状态&#xff1a; 求取平均值的时候出现了点问题 思路 C中&#xff0c;浮点数的相加会产生精度误差&#xff0c;求取平均值时最好只在最后一步进行…...

王学岗ASM

服务发现 package com.example.testasm;import android.content.Context; import android.os.Bundle;import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat;…...

【数据结构】—— 队列

1、队列的概念2、队列的结构如何选择合适的数据结构实现队列&#xff08;数组or链表&#xff09; 3、队列的链式存储3.1 队列的链式存储结构3.2 队列的常见接口3.3 队列的接口实现初始化判空入队列出队列获取队头元素获取队尾元素获取节点个数销毁 3.4 源代码 4、队列的顺序存储…...

vue中openlayers过滤高亮显示某个图层

vue中openlayers过滤高亮显示某个图层 openlayers库没有直接支持这样设置&#xff0c;所以可以使用库&#xff1a;ol-ext&#xff0c;地址&#xff1a;https://viglino.github.io/ol-ext/examples/filter/map.filter.crop.html 效果&#xff1a; 关键代码&#xff1a; /**…...

WPF篇(11)-ToolTip控件(提示工具)+Popup弹出窗口

ToolTip控件 ToolTip控件继承于ContentControl&#xff0c;它不能有逻辑或视觉父级&#xff0c;意思是说它不能以控件的形式实例化&#xff0c;它必须依附于某个控件。因为它的功能被设计成提示信息&#xff0c;当鼠标移动到某个控件上方时&#xff0c;悬停一会儿&#xff0c;…...

【mysql 第一篇章】系统和数据库的交互方法

一、宏观的查看系统怎么和数据库交互 在我们刚刚接触系统和数据库的时候不明白其中的原理&#xff0c;只知道系统和数据库是需要交互的。所以我们会理解成上图的形式。 二、MYSQL 驱动 随着我们的学习时间的加长以及对程序的了解&#xff0c;发现链接数据库是需要有别的工具辅…...

数据结构-位运算总结

位运算总结&#xff1a; 1.求位1的个数 191. 位1的个数 - 力扣&#xff08;LeetCode&#xff09; 有两种写法&#xff1a; 1.是把该数不断的去与0x1相与&#xff0c;得到该数的最后一位的值&#xff0c;然后判断他是不是1&#xff0c;再把该数更新一下整体往后移动一位也就…...

java 异常堆栈的由来

编写的程序代码内部错误产生的异常&#xff0c;如调用对象为空(空指针异常)、数组越界异常、除0异常等。这种通常称为未检查的异常&#xff08;Runtime异常子类&#xff09;&#xff0c;在虚拟机中执行时会集中处理这些异常。其他运行中异常&#xff0c;通过throw语句主动抛出的…...

【推荐系统】【多任务学习】Progressive Layered Extraction (PLE)

Progressive Layered Extraction (PLE): A Novel Multi-Task Learning (MTL) Model for Personalized Recommendations 文章目录 Progressive Layered Extraction (PLE): A Novel Multi-Task Learning (MTL) Model for Personalized Recommendations1 论文出处2 背景2.1 背景介…...

java -转win32/win64免安装jre环境运行

由于java 转为exe&#xff0c;只能在装有JDK环境的电脑运行&#xff0c; 发给其他人也不能运行&#xff0c;缺少环境&#xff0c;程序自己背着jre走 1.先打好jar 包 2.使用exe4j 把jar包转成exe 运行程序 3.使用inno stup &#xff0c;把exe运行程序加上jre环境 以下是具体实现…...

算法板子:容斥原理——求出 1∼n 中能被质数 p1,p2,…,pm 中的至少一个数整除的整数有多少个

1. 题目要点 1. 设&#xff1a;求1~10中能被质数2和3中至少一个数整除的数有多少个。1~10中能被质数2整除的数的集合记为S1{2,4,6,8,10}&#xff0c;能被质数3整除的数的集合记为S2{3,6,9}&#xff0c;能同时被质数2和3整数的数的集合为S1∩S2{6} 2. 这道题的目的是求S1∪S2∪S…...

用gurobipy求解带不等式约束条件的优化问题

1. 引入 在当今的数据驱动世界中&#xff0c;优化问题无处不在&#xff0c;从工程设计到经济模型&#xff0c;再到机器学习算法的调参&#xff0c;优化都是实现效率最大化、成本最小化或性能最优化的关键工具。 这里有一个典型的数学优化问题&#xff0c;目标是在给定的约束条…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...