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

news/2024/10/7 17:51:58 标签: java, 前端框架, spring boot, intellij-idea

目录

  • 前言
  • 一、与页面原型差距
    • 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语句

-- 查询并显示点位表所有的字段信息,同时显示每个点位的设备数量
SELECT
    n.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
FROM
    tb_node n
LEFT JOIN
    tb_vending_machine v ON n.id = v.node_id
GROUP BY
    n.id;

-- 根据区域id查询区域信息
select * from tb_region where id=1;
-- 根据合作商id查询合作商信息
select * from tb_partner where id=1;

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

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

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

java">@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">
  <!-- 分组查询每个点位下的设备数量 -->
    SELECT
    n.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
    FROM
    tb_node n
    LEFT JOIN
    tb_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 BY
    n.id
</select>

3.修改service层

INodeService

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

NodeServiceImpl

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

4. 修改controller层

NodeController

java">/**
 * 查询点位管理列表
 */
@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>javascript">
    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.id
        getRegion(_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框架的全局异常处理器来捕获这些错误信息,并返回更友好的提示信息给用户。这样,当用户遇到这种情况时,他们将收到一个清晰、易懂的提示,告知他们操作无法完成的原因。
修改全局异常处理器,添加以下内容
在这里插入图片描述

java">/**
 * 数据完整性异常
 */
@ExceptionHandler(DataIntegrityViolationException.class)
public AjaxResult handelDataIntegrityViolationException(DataIntegrityViolationException e) {

    if (e.getMessage().contains("foreign")) {

        return AjaxResult.error("无法删除,有其他数据引用");
    }
    return AjaxResult.error("您的操作违反了数据库中的完整性约束");
}

http://www.niftyadmin.cn/n/5693139.html

相关文章

No.6 笔记 | Linux操作系统基础:全面概览与核心要点

1. 简介与历史 1.1 起源 创始人&#xff1a;Linus Torvalds&#xff08;芬兰赫尔辛基大学学生&#xff09;初衷&#xff1a;设计一个替代Minix的全功能Unix操作系统首次发布&#xff1a;1991年10月5日&#xff0c;Linux v0.01版本 2. Linux特点 多用户多任务&#xff1a;用…

【编程基础知识】Java静态导入的艺术与实践

摘要 本文深入探讨了Java静态导入的概念、使用场景以及潜在的弊端。通过实际代码示例和流程图&#xff0c;您将了解如何有效地使用静态导入来简化代码&#xff0c;并提高开发效率。同时&#xff0c;文章将提供实用的表格对比和思维导图&#xff0c;帮助您全面掌握静态导入的知…

电脑操作技巧:如何恢复永久删除的婚礼照片

我们的生活充满了褪色和模糊的快照&#xff0c;是我们记忆的剪贴簿。尽管我们很想记住事情并坚持快乐的回忆&#xff0c;但随着时间的推移&#xff0c;它们会被冲走。为了避免这种情况并记住这些记忆&#xff0c;我们以照片的形式捕捉瞬间。这有助于缓解和分享那些快乐的时刻。…

【大数据】Flink CDC 实时同步mysql数据

目录 一、前言 二、Flink CDC介绍 2.1 什么是Flink CDC 2.2 Flink CDC 特点 2.3 Flink CDC 核心工作原理 2.4 Flink CDC 使用场景 三、常用的数据同步方案对比 3.1 数据同步概述 3.1.1 数据同步来源 3.2 常用的数据同步方案汇总 3.3 为什么推荐Flink CDC 3.4 Flink …

JAVA思维提升

利用java做一个双色球彩票系统 要求 package ZY; import java.util.Random; import java.util.Scanner; public class Test9双色球 { //目标&#xff1a;模拟双色球//规则投注号码由6个红色球号码和1个蓝色球号码组成。红色球号码从1-33中选择;蓝色球号码从1-16中选择。publi…

JS模块化工具requirejs详解

文章目录 JS模块化工具requirejs详解一、引言二、RequireJS 简介1、什么是 RequireJS2、RequireJS 的优势 三、RequireJS 的使用1、配置 RequireJS1.1、基础配置 2、定义模块3、加载模块 四、总结 JS模块化工具requirejs详解 一、引言 随着前端技术的快速发展&#xff0c;Jav…

Maven - 依赖管理

依赖配置 在pom.xml的project标签内添加dependencies标签&#xff0c;之后添加依赖配置。 <dependencies><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.4.5</version>…

用CSS创造三角形案例

6.3.2 用CSS创造三角形 用div来创建&#xff0c;角上是平分的&#xff0c;所以要是内部宽高为0&#xff0c;其他边透明&#xff0c;正好是三角形。 代码 div {border: 12px solid;width: 0;height: 0;border-color: transparent red transparent transparent; } 与伪元素aft…