多表之间存在父子级关系:根据某一级,查询所有子级 构建树结构数据

表park_project、park_project_sub 、building 、building_floor 、building_floor_room 存在父子级关系,并且确定是4层。

多表之间存在父子级关系,根据某一级,查询所有子级

现需要根据某一级,查询这一级下的所有子级,因为所有的子级都分布在不同的表中,如果一张一张表去依次查的话,显然不是很方便,所以需要把它们连接起来作查询。

<resultMap id="positionIdsResultMap" type="PositionIdsDTO"><id column="project_id"         property="projectId" /><id column="project_sub_id"     property="projectSubId" /><id column="building_id"        property="buildingId" /><id column="building_floor_id"  property="buildingFloorId" /><id column="room_id"            property="roomId" />
</resultMap><!-- 根据传入的 projectId 和 positionIdAndType 查询所有关联的位置类型和位置id -->
<select id="selectPositionIds"  resultMap="positionIdsResultMap">SELECTpp.id project_id,pps.id project_sub_id,b.id building_id,bf.id building_floor_id,bfr.id room_id,pp.delete_flag,pps.delete_flag,b.delete_flag,bf.delete_flag,bfr.delete_flagFROMpark_project ppLEFT JOIN park_project_sub pps ON pps.project_id = pp.idLEFT JOIN building b ON b.sub_project_id = pps.idLEFT JOIN building_floor bf ON bf.building_id = b.idLEFT JOIN building_floor_room bfr ON bfr.floor_id = bf.idWHERE 1 = 1AND pp.id = #{projectId}<if test="positionType == 1">AND pp.id = #{positionId}AND pp.delete_flag = 0</if><if test="positionType == 2">AND pps.id = #{positionId}AND pp.delete_flag = 0AND pps.delete_flag = 0</if><if test="positionType == 3">AND b.id = #{positionId,jdbcType=VARCHAR}AND pp.delete_flag = 0AND pps.delete_flag = 0AND b.delete_flag = 0</if><if test="positionType == 4">AND bf.id = #{positionId,jdbcType=VARCHAR}AND pp.delete_flag = 0AND pps.delete_flag = 0AND b.delete_flag = 0AND bf.delete_flag = 0</if><if test="positionType == 5">AND bfr.id = #{positionId,jdbcType=VARCHAR}AND pp.delete_flag = 0AND pps.delete_flag = 0AND b.delete_flag = 0AND bf.delete_flag = 0AND bfr.delete_flag = 0</if>
</select>

如上查询完成后,可在代码里针对查询出来的每条数据,根据当前查询的位置类型,作对应的处理

@Override
public List<String> selectPositionIds(String projectId, String positionIdAndType) {Set positionIdAndTypeSet= new TreeSet<String>();String[] split = positionIdAndType.split("-");// 位置idString positionId = split[0];// 位置类型String positionType = split[1];List<PositionIdsDTO> positionIdsDTOS = buildingFloorRoomRepository.selectPositionIds(projectId, positionId, positionType);// 如果没查询到对应的数据 直接返回nullif (positionIdsDTOS == null || positionIdsDTOS.size() == 0) {return new ArrayList<String>();}// 根据positionType返回对应数据(下面的应该还有问题,应该要再加1个是否为null的判断)if (positionType.equals(BuildingFloorRoomEnum.PROJECT.getCode())){positionIdsDTOS.forEach(dto -> {positionIdAndTypeSet.add(dto.getProjectId() + "-" + BuildingFloorRoomEnum.PROJECT.getCode());positionIdAndTypeSet.add(dto.getProjectSubId() + "-" + BuildingFloorRoomEnum.PROJECT_SUB.getCode());positionIdAndTypeSet.add(dto.getBuildingId() + "-" + BuildingFloorRoomEnum.BUILDING.getCode());positionIdAndTypeSet.add(dto.getBuildingFloorId() + "-" + BuildingFloorRoomEnum.BUILDING_FLOOR.getCode());positionIdAndTypeSet.add(dto.getRoomId() + "-" + BuildingFloorRoomEnum.BUILDING_FLOOR_ROOM.getCode());});}else if (positionType.equals(BuildingFloorRoomEnum.PROJECT_SUB.getCode())) {positionIdsDTOS.forEach(dto -> {positionIdAndTypeSet.add(dto.getProjectSubId() + "-" + BuildingFloorRoomEnum.PROJECT_SUB.getCode());positionIdAndTypeSet.add(dto.getBuildingId() + "-" + BuildingFloorRoomEnum.BUILDING.getCode());positionIdAndTypeSet.add(dto.getBuildingFloorId() + "-" + BuildingFloorRoomEnum.BUILDING_FLOOR.getCode());positionIdAndTypeSet.add(dto.getRoomId() + "-" + BuildingFloorRoomEnum.BUILDING_FLOOR_ROOM.getCode());});} else if (positionType.equals(BuildingFloorRoomEnum.BUILDING.getCode())) {positionIdsDTOS.forEach(dto -> {positionIdAndTypeSet.add(dto.getBuildingId() + "-" + BuildingFloorRoomEnum.BUILDING.getCode());positionIdAndTypeSet.add(dto.getBuildingFloorId() + "-" + BuildingFloorRoomEnum.BUILDING_FLOOR.getCode());positionIdAndTypeSet.add(dto.getRoomId() + "-" + BuildingFloorRoomEnum.BUILDING_FLOOR_ROOM.getCode());});} else if (positionType.equals(BuildingFloorRoomEnum.BUILDING_FLOOR.getCode())) {positionIdsDTOS.forEach(dto -> {positionIdAndTypeSet.add(dto.getBuildingFloorId() + "-" + BuildingFloorRoomEnum.BUILDING_FLOOR.getCode());positionIdAndTypeSet.add(dto.getRoomId() + "-" + BuildingFloorRoomEnum.BUILDING_FLOOR_ROOM.getCode());});} else if (positionType.equals(BuildingFloorRoomEnum.BUILDING_FLOOR_ROOM.getCode())) {positionIdsDTOS.forEach(dto -> {positionIdAndTypeSet.add(dto.getRoomId() + "-" + BuildingFloorRoomEnum.BUILDING_FLOOR_ROOM.getCode());});}return new ArrayList<>(positionIdAndTypeSet);}

在mybatisplus中拼接上and (条件1 or 条件2 or 条件3 …)

public List<FacilityLedger> listFacilityLedger(FacilityLedgerListParam param) {List<String> positionIds = param.getPositionIds();List<String[]> positions = null;if (CollUtil.isNotEmpty(positionIds)) {positions = positionIds.stream().map(positionId -> positionId.split("-")).filter(position -> position.length == 2).collect(Collectors.toList());}// 只允许查询某一个项目下的数据if (param != null && param.getProjectId() != null) {List<String[]> finalPositions = positions;LambdaQueryWrapper<FacilityLedger> wrapper = Wrappers.lambdaQuery(FacilityLedger.class)// 项目id.eq(FacilityLedger::getProjectId, param.getProjectId())// 未删除.eq(FacilityLedger::getDeleteFlag, StatusType.INVALID.getValue())// 设备id.in(CollUtil.isNotEmpty(param.getIds()), FacilityLedger::getId, param.getIds())// 分类id.in(CollUtil.isNotEmpty(param.getClassificationIds()), FacilityLedger::getClassificationId, param.getClassificationIds())// 重要等级.in(CollUtil.isNotEmpty(param.getImportanceLevels()), FacilityLedger::getImportanceLevel, param.getImportanceLevels())// 使用状态.in(CollUtil.isNotEmpty(param.getUseStatuss()), FacilityLedger::getUseStatus, param.getUseStatuss())// 责任部门id.in(CollUtil.isNotEmpty(param.getResponsibleDeptIds()), FacilityLedger::getResponsibleDeptId, param.getResponsibleDeptIds())// 大于等于首次启用时间 -开始.ge(param.getFirstEnabledTimeStart() != null, FacilityLedger::getFirstEnabledTime, param.getFirstEnabledTimeStart())// 小于等于首次启用时间 - 结束.le(param.getFirstEnabledTimeEnd() != null, FacilityLedger::getFirstEnabledTime, param.getFirstEnabledTimeEnd()).and(StringUtils.isNotEmpty(param.getNameKey()), (queryWrapper) -> queryWrapper.like(// 根据设备名字进行模糊查询StrUtil.isNotEmpty(param.getNameKey()), FacilityLedger::getFacilityName, param.getNameKey())// 根据分类编号进行模糊查询.or().like(StrUtil.isNotEmpty(param.getNameKey()), FacilityLedger::getClassificationCode, param.getNameKey())// 根据设备位置进行模糊查询.or().like(StrUtil.isNotEmpty(param.getNameKey()), FacilityLedger::getPositionDetails, param.getNameKey()))// 根据位置类型和位置id进行查询.and( CollUtil.isNotEmpty(finalPositions), wrapper1 -> {for (String[] position : finalPositions) {wrapper1.or().eq(FacilityLedger::getPositionId, position[0]).eq(FacilityLedger::getPositionType, position[1]);}}).last(" order by ISNULL(importance_level),importance_level asc, create_time desc ");List<FacilityLedger> list = list(wrapper);return list;}return Collections.emptyList();
}

多表之间存在父子级关系,构建树结构数据

  • 注意下面这个left join连接的时候的这个delete_flag条件是写在on这里的,而不是写在where后面,这是有区别的,写在on这里是连接条件,如果没有匹配的左边表的数据仍然会保留,而如果写在where后面,则即使匹配了,左表的数据仍然可能被过滤了
  • collection标签的使用
<resultMap id="ResourceTreeMap" type="ResourceNode"><id column="project_id" property="id"/><result column="project_name" property="name"/><result column="project_type" property="type"/><collection property="children" ofType="ResourceNode"><id column="sub_project_id" property="id"/><result column="sub_project_type" property="type"/><result column="sub_project_stage" property="name"/><collection property="children" ofType="ResourceNode"><id column="building_id" property="id"/><result column="building_type" property="type"/><result column="building_name" property="name"/><collection property="children" ofType="ResourceNode"><id column="floor_id" property="id"/><result column="floor_type" property="type"/><result column="floor_name" property="name"/><collection property="children" ofType="ResourceNode"><id column="room_id" property="id"/><result column="room_type" property="type"/><result column="room_name" property="name"/></collection></collection></collection></collection></resultMap>
<select id="selectRoomTree" resultMap="ResourceTreeMap">SELECTt.id AS project_id,( CASE WHEN f.id IS NOT NULL THEN 1 ELSE NULL END ) AS project_type,t.project_name,sub.id AS sub_project_id,( CASE WHEN f.id IS NOT NULL THEN 2 ELSE NULL END ) AS sub_project_type,CONCAT( sub.project_stage ) AS sub_project_stage,b.id AS building_id,( CASE WHEN f.id IS NOT NULL THEN 3 ELSE NULL END ) AS building_type,b.building_name AS building_name,f.id AS floor_id,( CASE WHEN f.id IS NOT NULL THEN 4 ELSE NULL END ) AS floor_type,f.floor_name AS floor_name,r.id AS room_id,( CASE WHEN r.id IS NOT NULL THEN 5 ELSE NULL END ) AS room_type,r.room_code AS room_nameFROMpark_project t LEFT JOIN park_project_sub sub on t.id = sub.project_id and sub.delete_flag = 0LEFT JOIN building b on sub.id = b.sub_project_id and b.delete_flag = 0LEFT JOIN building_floor f on b.id = f.building_id and f.delete_flag = 0LEFT JOIN building_floor_room r on f.id = r.floor_id and r.delete_flag = 0 and r.valid_state = 1where t.id = #{projectId}<if test="supportType != null">and r.support_business_type  like concat('%', #{surpportType}, '%')</if><if test="resourceName != null">and ( t.project_name like concat('%', #{resourceName}, '%')or sub.project_stage like concat('%', #{resourceName}, '%')or b.building_name like concat('%', #{resourceName}, '%')or f.floor_name like concat('%', #{resourceName}, '%')or r.room_code like concat('%', #{resourceName}, '%') )</if>ORDER BY sub.project_stage asc,b.id desc,f.sort_num asc,r.id desc
</select>
public class ResourceNode implements Serializable {/*** 资源ID*/private Long id;/*** 父级id*/private Long parentId;/*** 资源名称*/private String name;/*** 类型 1-园区,2-分期,3-楼宇,4楼层,5-房源(默认)*/private int type;/*** 子级*/private List<ResourceNode> children;/*** 备注*/private String remarks;/*** 父级名称*/private String parentName;public ResourceNode() {}public ResourceNode(Long id, Long parentId, String name, int type, String parentName) {this.id = id;this.parentId = parentId;this.name = name;this.type = type;this.parentName = parentName;}
}

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

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

相关文章

​软考-高级-系统架构设计师教程(清华第2版)【第10章 软件架构的演化和维护(P345~382)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第10章 软件架构的演化和维护&#xff08;P345~382&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

Matlab 方位角计算之二

文章目录 一、简介二、实现代码三、实现效果一、简介 我们总是说降维打击,这种思路尤其在一些问题上显现的尤为突出,就比如方位角这个问题,如果我们局限于二维这个空间,那么很多时候就需要判断方向向量落在了那个象限,之后再一个个情况逐一分析,虽然这样做并不复杂,但总…

【k8s集群搭建(二):基于虚拟机的linux的k8s集群搭建_超详细_可视化界面Dashboard安装_记录全过程踩坑记录及解决方法】

在 master 执行 # 根据 在线配置文件 创建资源 kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml设置访问端口 # 修改配置文件 找到 type&#xff0c;将 ClusterIP 改成 NodePort kubectl edit svc kubernetes-…

Scala---迭代器模式+Trait特质特性

Scala迭代器模式处理数据 scala中创建集合需要内存&#xff0c;集合与集合之间的转换时&#xff0c;每次转换生成新的集合时&#xff0c;新的集合也需要内存。如果有一个非常大的初始集合&#xff0c;需要经过多次转换&#xff0c;每次转换都生成一个新的集合&#xff0c;才能…

sqlite3简单使用

为什么要使用sqlite3? sqlite3轻量简介&#xff0c;无需单独的数据库服务&#xff0c;只需访问磁盘上的.db的文件。在某些情况下很有用。 下面是一些简单的使用代码&#xff1a; import sqlite3 from uuid import uuid1# 连接数据库文件&#xff0c;如果不存在会创建 with…

2023年中国冲击波治疗仪市场发展趋势分析:未来市场增长空间更大[图]

冲击波在临床医学领域最早应用于体外冲击波碎石&#xff0c;在二十世纪八十年代末期&#xff0c;体外冲击波碎石技术开始被运用到骨科及康复理疗领域&#xff0c;经过十余年的临床研究&#xff0c;冲击波疗法日益完善&#xff0c;应用范围也日益扩大。冲击波作为一种介于保守疗…

【入门篇】1.7 Redis 之 codis 入门介绍

文章目录 1. 简介2. Codis的安装与配置下载编译源码安装1. 安装 Go 运行环境2. 设置编译环境3. 下载 Codis 源代码4. 编译 Codis 源代码 Docker 部署 3. Codis的架构Codis的架构图和组件Codis的工作流程 4. Codis的核心特性自动数据分片数据迁移高可用性全面支持Redis命令分布式…

Android中eBPF使用原理以及 kprobe dmabuf_setup实例

目录 eBPF in Android Android eBPF kprobe dma代码 定义一个MAP 定义一个 PROG bpfprogs/Android.bp 测试程序 bpfprogs/memstats/Android.bp bpfprogs/memstats/MemStats.h bpfprogs/memstats/MemStats.cpp bpfprogs/memstats/MemStatsMain.cpp 编译运行 结果分析…

android 13.0 删除连接wifi的配置信息

1.前言 在13.0的系统rom产品定制化开发中,对于wifi的功能定制需求功能也是挺多的,目前对于wifi模块有这么个需求,要求在 提供接口实现删除已连接wifi的需求,所以需要了解wifi相关的配置情况,然后移除wifi即可,接下来就来实现相关的功能 2.删除连接wifi的配置信息的核心类…

C 语言 sizeof运算符

C 语言 sizeof运算符 sizeof运算符在C语言中使用时&#xff0c;它决定表达式的大小或在char大小的存储单元数量中指定的数据类型。sizeof运算符包含一个操作数&#xff0c;该操作数可以是表达式&#xff0c;也可以是数据类型转换&#xff0c;其中转换是用括号括起来的数据类型…

【fbtft】如何添加fbtft驱动

获取lcd ic的datasheet&#xff0c;或者直接找到其他平台&#xff08;linux&#xff0c;stm32&#xff0c;esp32&#xff09;的驱动 我用的是合宙的esp32驱动&#xff0c;注意是c语言的&#xff0c;合宙上层用lua封装了&#xff0c;需要找到sdk源码。 源码路径&#xff1a; …

File类和IO流

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

设置chunk自动扩展到多大

1. 设置chunk自动扩展 execute function task(modify chunk extendable on,8); 2. 设置dbs扩展到多大合适 execute function task(modify space sp sizes,testdb1024,1024,10240) testdb 初始1MB 下次扩1MB 最大10MB

appium+python自动化测试

获取APP的包名 1、aapt即Android Asset Packaging Tool&#xff0c;在SDK的build-tools目录下。该工具可以查看apk包名和launcherActivity 2、在android-sdk里面双击SDK-manager,下载buidl-tools 3、勾选build-tools&#xff0c;随便选一个版本&#xff0c;我这里选的是24的版…

宏集干货 | 手把手教你通过CODESYS V3进行PLC编程(三)

来源&#xff1a;宏集科技 工业物联网 宏集干货 | 手把手教你通过CODESYS V3进行PLC编程&#xff08;三&#xff09; 教程背景 通过之前的教程&#xff0c;我们已经为大家演示了宏集MC-Prime控制器的连接、试运行和CODESYS的安装&#xff0c;并创建了一个计数器项目。在本期教…

数据分析 - 分散性与变异的量度

全距 - 极差 处理变异性 方差度量 数值与均值的距离&#xff0c;也就是数据的差异性 标准差描述&#xff1a;典型值 和 均值的距离的方法&#xff0c;数据与均值的分散情况

出行类app如何提升广告变现收益?

出行类APP已经成为越来越多人们出行的首选&#xff0c;出行类app在变现方式上存在以下痛点&#xff1a;APP功能单一、使用场景单一&#xff1b;用户使用时间集中&#xff0c;粘性低...这些痛点使得开发者获取收益的提升面临极大的挑战。 https://www.shenshiads.com 如何让出…

事实 读书笔记

事实 这本书目标是想突破人类的一些本能的直觉惯性&#xff0c;让我们能更加客观的认识这个世界&#xff0c;让我们不显得那么无知。 主体内容以一些直觉陷阱一步一步的展开 二元论 作者认为我们很容易通过简单的对立关系来理解世界&#xff0c;如把这个世界理解为发展中国家…

【ARL灯塔搭建详细教程】

文章目录 前言一、前期准备二、安装docker及docker-compose三、安装ARL灯塔四、登录ARL灯塔 前言 ARL&#xff08;Asset Reconnaissance Lighthouse&#xff09;资产侦查灯塔旨在快速发现并整理企业外网资产并为资产构建基础数据库&#xff0c;无需登录凭证或特殊访问即可主动…

Python ... takes 0 positional arguments but 1 was given

最近&#xff0c;博主在学习python时遇到这么个报错&#xff0c; 系统&#xff1a;windows10 开发环境&#xff1a;VS Code Python版本&#xff1a;3.12 错误重现&#xff1a; class Dog:def __init__(self):passdef eatSomething(self):self.eatBone()def eatBone():prin…