3.点位管理改造-列表查询——帝可得管理系统

目录

  • 前言
  • 一、与页面原型差距
    • 1.现在:
    • 2.目标:
    • 3. 存在问题:
  • 二、修改
    • 1.重新设计SQL语句
    • 2.修改mapper层,使用Mybatis中的嵌套查询
    • 3.修改service层
    • 4. 修改controller层
    • 5.前端修改
    • 6.补充区域查看详情
    • 7.数据完整性

前言

提示:本篇目的是将点位管理中所在区域和合作商展示的ID改为对应的名称

一、与页面原型差距

1.现在:

在这里插入图片描述
点位管理的响应字段

{"total": 3,"rows": [{"createBy": null,"createTime": "2024-07-03 10:26:05","updateBy": null,"updateTime": "2024-07-03 10:26:05","remark": null,"id": 1,"nodeName": "三里屯点位","address": "北京市朝阳区三里屯路","businessType": 1,"regionId": 1,"partnerId": 1}...],"code": 200,"msg": "查询成功"
}

2.目标:

在这里插入图片描述
要求响应 返回的类型
在这里插入图片描述

3. 存在问题:

所在区域和合作商ID展示的都是ID,而不是名称;同时合作商ID应改为合作商
现阶段后端返回字段和目标字段对比,发现缺少region和partner信息

二、修改

1.重新设计SQL语句

-- 查询并显示点位表所有的字段信息,同时显示每个点位的设备数量
SELECTn.id,n.node_name,n.address,n.business_type,n.region_id,n.partner_id,n.create_time,n.update_time,n.create_by,n.update_by,n.remark,COUNT(v.id) AS vm_count
FROMtb_node n
LEFT JOINtb_vending_machine v ON n.id = v.node_id
GROUP BYn.id;-- 根据区域id查询区域信息
select * from tb_region where id=1;
-- 根据合作商id查询合作商信息
select * from tb_partner where id=1;

解释:上述第一条SQL查询了每个点位下的设备数量;后两条分别查询指定ID后,所对应的区域和合作商的全部信息。

2.修改mapper层,使用Mybatis中的嵌套查询

NodeVo:定义了返回给前端的字段。

@Data
public class NodeVo extends Node {// 设备数量private int vmCount;// 区域private Region region;// 合作商private Partner partner;
}

NodeMapper.java

/*** 查询点位管理列表* @param node* @return NodeVo集合*/
public List<NodeVo> selectNodeVoList(Node node);

NodeMapper.xml

  <!-- 返回结果:NodeVo  -->
<resultMap type="NodeVo" id="NodeVoResult"><!-- 从select中获取查询结果后,将column(数据库字段)与property(Java类字段)一一对应 --><result property="id"    column="id"    /><result property="nodeName"    column="node_name"    /><result property="address"    column="address"    /><result property="businessType"    column="business_type"    /><result property="regionId"    column="region_id"    /><result property="partnerId"    column="partner_id"    /><result property="createTime"    column="create_time"    /><result property="updateTime"    column="update_time"    /><result property="createBy"    column="create_by"    /><result property="updateBy"    column="update_by"    /><result property="remark"    column="remark"    /><result property="vmCount"    column="vm_count"    /><!-- 将column(数据库字段)作为条件传到select中进行条件查询,结果封装到property中,因因property为类对象,所以指定了JavaType(类) --><association property="region" javaType="Region" column="region_id" select="com.dkd.manage.mapper.RegionMapper.selectRegionById"/><association property="partner" javaType="Partner" column="partner_id" select="com.dkd.manage.mapper.PartnerMapper.selectPartnerById"/>
</resultMap><!-- id与函数名相同,resultMap为最终返回类型:NodeVo -->
<select id="selectNodeVoList" resultMap="NodeVoResult"><!-- 分组查询每个点位下的设备数量 -->SELECTn.id,n.node_name,n.address,n.business_type,n.region_id,n.partner_id,n.create_time,n.update_time,n.create_by,n.update_by,n.remark,COUNT(v.id) AS vm_countFROMtb_node nLEFT JOINtb_vending_machine v ON n.id = v.node_id<where><if test="nodeName != null  and nodeName != ''"> and n.node_name like concat('%', #{nodeName}, '%')</if><if test="regionId != null "> and n.region_id = #{regionId}</if><if test="partnerId != null "> and n.partner_id = #{partnerId}</if></where>GROUP BYn.id
</select>

3.修改service层

INodeService

/*** 查询点位管理列表* @param node* @return NodeVo集合*/
public List<NodeVo> selectNodeVoList(Node node);

NodeServiceImpl

/*** 查询点位管理列表** @param node* @return NodeVo集合*/
@Override
public List<NodeVo> selectNodeVoList(Node node) {return nodeMapper.selectNodeVoList(node);
}

4. 修改controller层

NodeController

/*** 查询点位管理列表*/
@PreAuthorize("@ss.hasPermi('manage:node:list')")
@GetMapping("/list")
public TableDataInfo list(Node node)
{startPage(); //开始分页List<NodeVo> voList = nodeService.selectNodeVoList(node); //以node为条件进行查询,结果分装到NOdeVo类中return getDataTable(voList); //将NodeVo转为TableDataInfo
}

5.前端修改

node/index.vue

<!-- 点位列表 -->
<el-table v-loading="loading" :data="nodeList" @selection-change="handleSelectionChange"><el-table-column type="selection" width="55" align="center" /><el-table-column label="序号" type="index" width="50" align="center" prop="id" /><el-table-column label="点位名称" align="center" prop="nodeName" /><el-table-column label="所在区域" align="center" prop="region.regionName" /><el-table-column label="商圈类型" align="center" prop="businessType"><template #default="scope"><dict-tag :options="business_type" :value="scope.row.businessType" /></template></el-table-column><el-table-column label="合作商" align="center" prop="partner.partnerName" /><el-table-column label="详细地址" align="center" prop="address" show-overflow-tooltip="true"/><el-table-column label="操作" align="center" class-name="small-padding fixed-width"><template #default="scope"><el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['manage:node:edit']">修改</el-button><el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['manage:node:remove']">删除</el-button></template></el-table-column></el-table>

6.补充区域查看详情

在region/index.vue视图组件中修改

<el-button link type="primary" @click="getRegionInfo(scope.row)" v-hasPermi="['manage:node:list']">查看详情</el-button><!-- 查看详情对话框 -->
<el-dialog title="区域详情" v-model="regionInfoOpen" width="500px" append-to-body><el-form-item label="区域名称" prop="regionName"><el-input v-model="form.regionName" disabled /></el-form-item><label>包含点位:</label><el-table :data="nodeList"><el-table-column label="序号" type="index" width="50" align="center" /><el-table-column label="点位名称" align="center" prop="nodeName" /><el-table-column label="设备数量" align="center" prop="vmCount" /></el-table></el-dialog><script>import { listNode } from "@/api/manage/node";import { loadAllParams } from "@/api/page";/* 查看详情按钮操作 */const nodeList = ref([]);const regionInfoOpen = ref(false);function getRegionInfo(row) {// 查询区域信息reset();const _id = row.idgetRegion(_id).then(response => {form.value = response.data;});// 查询点位列表loadAllParams.regionId = row.id;listNode(loadAllParams).then(response => {nodeList.value = response.rows;});regionInfoOpen.value = true;
</script>

7.数据完整性

现在我们要思考一个问题,当我们删除区域或合作商数据时,与之关联的点位数据该如何处理?
在这里插入图片描述

在默认情况下,由于我们在创建点位表时通过AI设置了外键约束,并配置了级联删除操作,所以删除区域或合作商会导致其关联的点位数据一并被删除。从技术角度来看,这是符合数据库的外键约束规则的。
但是,从业务角度来看,这种做法可能不太合适。想象一下,如果一个区域下有多个点位,一次误操作就可能导致所有的点位数据及其关联的设备信息被一并删除,这显然是我们不愿意看到的。
因此,我们需要对级联操作进行修改,将其改为限制删除。这样,当尝试删除一个区域或合作商时,如果它下面还有关联的点位数据,数据库将不会允许删除操作,并会给出错误提示。

使用Navicat修改tb_node表:
在这里插入图片描述

CASCADE(级联操作):当父表中的某行记录被删除或更新时,与其关联的所有子表中的匹配行也会自动被删除或更新。这种方式适用于希望保持数据一致性的场景,即父记录不存在时,相关的子记录也应该被移除。
SET NULL(设为空):若父表中的记录被删除或更新,子表中对应的外键字段会被设置为NULL。选择此选项的前提是子表的外键列允许为NULL值。这适用于那些子记录不再需要明确关联到任何父记录的情况。
RESTRICT(限制):在尝试删除或更新父表中的记录之前,数据库首先检查是否有相关联的子记录存在。如果有,则拒绝执行删除或更新操作,以防止意外丢失数据或破坏数据关系的完整性。这是一种保守策略,确保数据间的引用完整性。
NO ACTION(无操作):在标准SQL中,NO ACTION是一个关键字,它要求数据库在父表记录被删除或更新前,检查是否会影响子表中的相关记录。在MySQL中,NO ACTION的行为与RESTRICT相同,即如果子表中有匹配的行,则禁止执行父表的删除或更新操作。这意味着如果存在依赖关系,操作将被阻止,从而保护数据的参照完整性。
修改完毕后,如果你尝试进行删除操作,会发现数据库的完整性约束生效了,它会阻止删除操作并给出错误提示。但是,这个错误提示信息可能对于用户来说不够友好,可能会让用户感到困惑。
在这里插入图片描述
SQLIntegrityConstraintViolationException是Java中的一个异常类,这个类通常用于表示SQL数据库操作中的完整性约束违反异常
例如:外键约束、唯一约束等。当数据库操作违反了这些约束时,就会抛出这个异常。
这个错误是由于外键约束导致的。它表明在删除或更新父表的行时,存在外键约束,子表中的相关行会受到影响。
是因为在删除tb_region表中的行时,tb_node表中的region_id外键约束会阻止操作。
如果你在使用Spring框架进行数据库操作,可能会先遇到DataIntegrityViolationException,它是对SQLIntegrityConstraintViolationException的一个更高层次的抽象,旨在提供一种更加面向应用的错误表示。
而SQLIntegrityConstraintViolationException是更底层的异常,直接来源于数据库驱动,包含更多底层数据库相关的细节。
在实际开发中,推荐捕获并处理DataIntegrityViolationException,因为它更符合Spring应用的异常处理模式,同时也可以通过其内部的cause(原因)属性来获取具体的SQLIntegrityConstraintViolationException,进而获取详细的错误信息。

为了提升用户体验,我们可以使用Spring Boot框架的全局异常处理器来捕获这些错误信息,并返回更友好的提示信息给用户。这样,当用户遇到这种情况时,他们将收到一个清晰、易懂的提示,告知他们操作无法完成的原因。
修改全局异常处理器,添加以下内容
在这里插入图片描述

/*** 数据完整性异常*/
@ExceptionHandler(DataIntegrityViolationException.class)
public AjaxResult handelDataIntegrityViolationException(DataIntegrityViolationException e) {if (e.getMessage().contains("foreign")) {return AjaxResult.error("无法删除,有其他数据引用");}return AjaxResult.error("您的操作违反了数据库中的完整性约束");
}

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

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

相关文章

《OpenCV 计算机视觉》—— 视频背景建模

文章目录 一、背景建模的目的二、背景建模的方法三、背景建模的步骤四、注意事项五、代码实现 一、背景建模的目的 视频背景建模的主要目的是从视频序列中提取出静态背景&#xff0c;以便将动态的前景对象与静态的背景进行分离。这有助于进一步分析和处理视频内容&#xff0c;…

【Mybatis篇】Mybatis的关联映射详细代码带练 (多对多查询、Mybatis缓存机制)

&#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【计算机网络】,【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录 &#x1f3af;一.关联映射概述 &#x1f6a…

RTSP协议讲解

1.RTSP协议 rtsp&#xff0c;英文全称 Real Time Streaming Protocol&#xff0c;RFC2326&#xff0c;实时流传输协议&#xff0c;是 TCP/IP 协议体系中的一个应用层协议。 RTSP 交互流程 1&#xff09;OPTIONS C--->S 客户端向服务器端发现 OPTIONS&#xff0c;请求可用…

html中的文本标签(含标签的实现案例)

目录 1.标题标签 2.标题标签的align属性 3.段落标签 4.水平线标签hr 5.换行标签br 6.文本样式标签font ​编辑7.文本格式化标签 8.文本语义标签 1&#xff09;时间time标签 2&#xff09;文本高亮Mark标签 3&#xff09;cite标签 9.特殊字符标签 10.图像标签img 附录&#xff…

基于微信小程序的旅游拼团系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

gitee公钥设置、创建库及使用

简介 一、如何安装git 使用gitee&#xff0c;需要先安装git工具。 工具网站地址&#xff1a;https://git-scm.com/downloads 安装完成后&#xff0c;在terminal命令行输入git --version可以查看到git的版本。 二、登录gitee 我们先在 gitee上注册账号并登录。gitee官网&#x…

震动传感器介绍及实战

目录 前言 震动传感器 1.震动传感器配图 2.震动传感器原理图 3.震动传感器使用 1-震动传感器的意义 2-震动传感器的应用场景 3- SW-18010P震动传感器使用方法 震动传感器控制灯 操作 增加延时 使用SPC-ISP生成演示函数 总结 前言 我们上节已经简单了解了LED的使用…

二、变量与基本类型

变量与基本类型 变量定义声明和使用 基本类型数字类型介绍运算算术运算符位运算符赋值运算符运算符优先级 布尔类型字符类型字符串类型 变量 定义 变量&#xff0c;指值可以变的量。变量以非数字的符号来表达&#xff0c;一般用拉丁字母。变量的用处在于能一般化描述指令的方式…

MongoDB集群模式详解及应用实战

目录 本节课内容&#xff1a; 集群搭建 1.创建3个目录&#xff1a; 2.编辑配置文件 ​编辑 3.启动&#xff1a; 4.看看&#xff1a; 5.另外&#xff0c;两个如上1&#xff0c;2&#xff0c;3步骤操作 &#xff0c;但是日志目录&#xff0c;端口什么的需要改一下即可。 …

10以内数的分解

// 10以内数的分解.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //#include <iostream> using namespace std; int main(int argc, char* argv[]){for (int i 2; i < 10; i){for (int j 1; j < i; j){printf("%d%d%d ",j…

操作系统学习笔记---文件管理

文件系统基础 概念 文件&#xff1a;以计算机硬盘为载体的存储在计算机上的信息集合 文件的属性 文件具有一定的属性&#xff0c;系统不同&#xff0c;属性也会有所不同&#xff0c;但通第都包括如下属性&#xff1a;名称、标识符、类型、位置、大小、保护、时间、日期和用…

vue3+vite@4+ts+elementplus创建项目详解

1、第一步创建项目cnpm init vite4 2、设置vue3.2局域网可访问配置&#xff1a; 找到项目路径下的package.json目录下找到script对象下面添加一下代码&#xff1a; "serve": "vite --host 0.0.0.0" 启动项目命令不在是dev而是&#xff1a;cnpm run serve 3…

《深度学习》OpenCV 摄像头OCR 过程及案例解析

目录 一、摄像头OCR 1、含义 2、一般操作步骤 1&#xff09;安装OpenCV库 2&#xff09;设置摄像头 3&#xff09;图像采集 4&#xff09;图像预处理 5&#xff09;文本识别 6&#xff09;文本处理 7&#xff09;结果显示 二、案例实现 1、定义展示图像函数 2、定…

深入理解 JavaScript 事件循环机制:单线程中的异步处理核心

深入理解 JavaScript 事件循环机制&#xff1a;单线程中的异步处理核心 JavaScript 是一门单线程的编程语言&#xff0c;也就是说它在同一时间只能执行一个任务。然而&#xff0c;现代 Web 应用经常需要处理大量的异步操作&#xff0c;如用户输入、网络请求、定时器等。为了确…

《迁移学习》—— 将 ResNet18 模型迁移到食物分类项目中

文章目录 一、迁移学习的简单介绍1.迁移学习是什么&#xff1f;2.迁移学习的步骤 二、数据集介绍三、代码实现1. 步骤2.所用到方法介绍的文章链接3. 完整代码 一、迁移学习的简单介绍 1.迁移学习是什么&#xff1f; 迁移学习是指利用已经训练好的模型&#xff0c;在新的任务上…

鸿蒙开发(NEXT/API 12)【状态查询与订阅】手机侧应用开发

注意 该接口的调用需要在开发者联盟申请设备基础信息权限与穿戴用户状态权限&#xff0c;穿戴用户状态权限还需获得用户授权。 实时查询穿戴设备可用空间、电量状态。订阅穿戴设备连接状态、低电量告警、用户心率告警。查询和订阅穿戴设备充电状态、佩戴状态、设备模式。 使…

初识Django

前言: 各位观众老爷们好&#xff0c;最近几个月都没怎么更新&#xff0c;主要是最近的事情太多了&#xff0c;我也在继续学习Django框架&#xff0c;之前还参加了一些比赛&#xff0c;现在我会开始持续更新Django的学习&#xff0c;这个过程会比较久&#xff0c;我会把我学习的…

MySQL--三大范式(超详解)

目录 一、前言二、三大范式2.1概念2.2第一范式&#xff08;1NF&#xff09;2.3第二范式&#xff08;2NF&#xff09;2.3第三范式&#xff08;3NF&#xff09; 一、前言 欢迎大家来到权权的博客~欢迎大家对我的博客进行指导&#xff0c;有什么不对的地方&#xff0c;我会及时改进…

嘴尚绝卤味:健康美味的双重奏

在当今快节奏的生活中&#xff0c;人们对美食的追求不再仅仅停留于味蕾的满足&#xff0c;更加注重食物的健康与营养。在这一背景下&#xff0c;"嘴尚绝卤味"以其独特的健康理念与精湛的制作工艺&#xff0c;成为了市场上备受瞩目的卤味品牌。本文将从"嘴尚绝卤…

Kotlin基本知识

Kotlin是一种现代的静态类型编程语言&#xff0c;由JetBrains公司在2010年推出&#xff0c;并被Google在2019年宣布为Android开发的首选语言。 超过 50% 的专业 Android 开发者使用 Kotlin 作为主要语言&#xff0c;而只有 30% 使用 Java 作为主要语言。 70% 以 Kotlin 为主要语…