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

第四阶段10-添加类别,类别列表mapper层,service层,controller层

63. 添加类别–Mapper层

插入类别数据的功能此前已经完成!

64. 添加类别–Service层

在项目的根包下创建pojo.dto.CategoryAddNewDTO类:

@Data
public class CategoryAddNewDTO implements Serializable {/*** 类别名称*/private String name;/*** 父级类别id,如果无父级,则为0*/private Long parentId;/*** 关键词列表,各关键词使用英文的逗号分隔*/private String keywords;/*** 排序序号*/private Integer sort;/*** 图标图片的URL*/private String icon;/*** 是否启用,1=启用,0=未启用*/private Integer enable;/*** 是否显示在导航栏中,1=启用,0=未启用*/private Integer isDisplay;}

在项目的根包下创建service.ICategoryService接口,并在接口中添加抽象方法:

public interface ICategoryService {void addNew(CategoryAddNewDTO categoryAddNewDTO);
}

在项目的根包下创建service.impl.CategoryServiceImpl类,实现以上接口,并在类上添加@Service注解,然后,实现接口中的方法:

@Service
public class CategoryServiceImpl implements ICategoryService {public void addNew(CategoryAddNewDTO categoryAddNewDTO) {// 调用Mapper对象的countByName()检查类别名称是否已经被占用// 是:抛出异常(ERR_CONFLICT)// 如果parentId不是0,调用Mapper对象的getStandardById()查询类别详情// 判断查询结果是否为null// 是:父级类别不存在,抛出异常(NOT_FOUND)// depth(深度)的值:如果父级类别id为0,则depth为1,否则,depth为父级depth+1// 创建Category类的对象// 将参数对象中的各属性值复制到以上新创建的Category类的对象中// 补全Category类的对象的属性值:depth// 补全Category类的对象的属性值:isParent >>> 固定为0// 调用Mapper对象的insert()方法插入类别数据// 如果现在添加的类别的父级类别不是0,// 如果父级类别的isParent仍为0// 则将父级类别的isParent更新为1}}

具体实现为:

@Override
public void addNew(CategoryAddNewDTO categoryAddNewDTO) {log.debug("开始处理【添加类别】的业务,参数:{}", categoryAddNewDTO);// 调用Mapper对象的countByName()检查类别名称是否已经被占用String name = categoryAddNewDTO.getName();int countByName = categoryMapper.countByName(name);if (countByName > 0) {// 是:抛出异常(ERR_CONFLICT)String message = "添加类别失败,尝试添加的类别名称【" + name + "】已经被占用!";log.warn(message);throw new ServiceException(ServiceCode.ERR_CONFLICT, message);}Integer depth = 1;CategoryStandardVO parentCategory = null;Long parentId = categoryAddNewDTO.getParentId();if (parentId != 0) {// 如果parentId不是0,调用Mapper对象的getStandardById()查询类别详情parentCategory = categoryMapper.getStandardById(parentId);// 判断查询结果是否为nullif (parentCategory == null) {// 是:父级类别不存在,抛出异常(NOT_FOUND)String message = "添加类别失败,选定的父级类别不存在!";log.warn(message);throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);} else {depth = parentCategory.getDepth() + 1;}}// 创建Category类的对象Category category = new Category();// 将参数对象中的各属性值复制到以上新创建的Category类的对象中BeanUtils.copyProperties(categoryAddNewDTO, category);// 补全Category类的对象的属性值:depthcategory.setDepth(depth);// 补全Category类的对象的属性值:isParent >>> 固定为0category.setIsParent(0);// 调用Mapper对象的insert()方法插入类别数据categoryMapper.insert(category);// 如果现在添加的类别的父级类别不是0if (parentId != 0) {// 如果父级类别的isParent仍为0if (parentCategory.getIsParent() == 0) {// 则将父级类别的isParent更新为1Category updateParentCategory = new Category();updateParentCategory.setId(parentId);updateParentCategory.setIsParent(1);categoryMapper.update(updateParentCategory);}}
}

在项目的src/test/java下的根包下创建CategoryServiceTests类,对以上方法进行测试:

@Slf4j
@SpringBootTest
public class CategoryServiceTests {@AutowiredICategoryService service;@Testvoid addNew() {CategoryAddNewDTO categoryAddNewDTO = new CategoryAddNewDTO();categoryAddNewDTO.setParentId(74L);categoryAddNewDTO.setName("热带水果");try {service.addNew(categoryAddNewDTO);log.debug("添加类别成功!");} catch (ServiceException e) {log.debug("捕获到异常,其中的消息:{}", e.getMessage());}}}

65. 添加类别–Controller层

在项目的根包下创建controller.CategoryController类,在类上添加@RestController注解和@RequestMapping("/categories")注解,在类中自动装配ICategoryService类型的对象:

@RestController
@RequestMapping("/categories")
public class CategoryController {@Autowiredprivate ICategoryService categoryService;
}

然后,在此类中处理请求:

@PostMapping("/add-new")
public JsonResult<Void> addNew(CategoryAddNewDTO categoryAddNewDTO) {log.debug("xxx");categoryService.addNew(categoryAddNewDTO);return JsonResult.ok();
}

完成后,重启项目,可以通过在线API文档进行调试。

调试通过后,应该补充在线API文档的相关说明。

提示:接下来,在课上不再对请求参数的基本格式进行检查。

66. 删除类别–Mapper层

67. 删除类别–Service层

ICategoryService接口中添加抽象方法:

/*** 根据id删除类别** @param id 类别id*/
void delete(Long id);

CategoryServiceImpl中实现以上方法:

public void delete(Long id) {// 调用Mapper对象的getStandardById()执行查询// 判断查询结果是否为null// 是:数据已经不存在,抛出异常(NOT_FOUND)// 判断以上查询结果中的isParent是否为1// 是:当前尝试删除的是父级类别,抛出异常(CONFLICT)// 调用BrandCategoryMapper对象的countByCategory()执行统计// 判断统计结果是否大于0// 是:当前尝试删除的类别关联到了某些品牌,抛出异常(CONFLICT)// 调用CategoryAttributeTemplateMapper对象的countByCategory()执行统计// 判断统计结果是否大于0// 是:当前尝试删除的类别关联到了某些属性模板,抛出异常(CONFLICT)// 调用SpuMapper对象的countByCategory()执行统计// 判断统计结果是否大于0// 是:当前尝试删除的类别关联到了某些SPU,抛出异常(CONFLICT)// 调用Mapper对象的deleteById()执行删除// 从此前的查询结果中找到当前删除的类别的父级类别ID// 判断父级类别ID是否不为0// 调用Mapper对象的countByParentId()执行统计// 判断统计结果是否等于0// 是:将父级类别的isParent更新为0
}

具体实现为:

@Override
public void delete(Long id) {// 调用Mapper对象的getStandardById()执行查询CategoryStandardVO currentCategory = categoryMapper.getStandardById(id);// 判断查询结果是否为nullif (currentCategory == null) {// 是:数据已经不存在,抛出异常(NOT_FOUND)String message = "删除类别失败,尝试删除的类别不存在!";log.warn(message);throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);}// 判断以上查询结果中的isParent是否为1if (currentCategory.getIsParent() == 1) {// 是:当前尝试删除的是父级类别,抛出异常(CONFLICT)String message = "删除类别失败,尝试删除的类别仍包含子级类别!";log.warn(message);throw new ServiceException(ServiceCode.ERR_CONFLICT, message);}{// 调用BrandCategoryMapper对象的countByCategory()执行统计int count = brandCategoryMapper.countByCategory(id);// 判断统计结果是否大于0if (count > 0) {// 是:当前尝试删除的类别关联到了某些品牌,抛出异常(CONFLICT)String message = "删除类别失败,尝试删除的类别关联了某些品牌!";log.warn(message);throw new ServiceException(ServiceCode.ERR_CONFLICT, message);}}{// 调用CategoryAttributeTemplateMapper对象的countByCategory()执行统计int count = categoryAttributeTemplateMapper.countByCategory(id);// 判断统计结果是否大于0if (count > 0) {// 是:当前尝试删除的类别关联到了某些属性模板,抛出异常(CONFLICT)String message = "删除类别失败,尝试删除的类别关联了某些属性模板!";log.warn(message);throw new ServiceException(ServiceCode.ERR_CONFLICT, message);}}{// 调用SpuMapper对象的countByCategory()执行统计int count = spuMapper.countByCategory(id);// 判断统计结果是否大于0if (count > 0) {// 是:当前尝试删除的类别关联到了某些SPU,抛出异常(CONFLICT)String message = "删除类别失败,尝试删除的类别关联了某些SPU!";log.warn(message);throw new ServiceException(ServiceCode.ERR_CONFLICT, message);}}// 调用Mapper对象的deleteById()执行删除log.debug("即将执行删除类别,参数:{}", id);categoryMapper.deleteById(id);// 从此前的查询结果中找到当前删除的类别的父级类别IDLong parentId = currentCategory.getParentId();// 判断父级类别ID是否不为0if (parentId != 0) {// 调用Mapper对象的countByParentId()执行统计int count = categoryMapper.countByParentId(parentId);// 判断统计结果是否等于0if (count == 0) {// 是:将父级类别的isParent更新为0Category parentCategory = new Category();parentCategory.setId(parentId);parentCategory.setIsParent(0);categoryMapper.update(parentCategory);}}
}

CategoryServiceTests中编写并执行测试:

@Test
void delete() {Long id = 74L;try {service.delete(id);log.debug("删除类别成功!");} catch (ServiceException e) {log.debug("捕获到异常,其中的消息:{}", e.getMessage());}
}

相关文章:

第四阶段10-添加类别,类别列表mapper层,service层,controller层

63. 添加类别–Mapper层 插入类别数据的功能此前已经完成&#xff01; 64. 添加类别–Service层 在项目的根包下创建pojo.dto.CategoryAddNewDTO类&#xff1a; Data public class CategoryAddNewDTO implements Serializable {/*** 类别名称*/private String name;/*** 父…...

linux内核启动分析(一)

文章目录1.HEAD1.preserve_boot_args1.1 __inval_dcache_area2.el2_setup3. set_cpu_boot_mode_flag4. __create_page_tables4.1map_memory5. __cpu_setup6. __primary_switch6.1 __enable_mmu6.2 __primary_switched最近工作中经常使用飞腾E2000的开发版&#xff0c;也遇到一些…...

wireshark常见使用操作讲解以及几个故障解决案例分享

&#xff08;1&#xff09;网卡选择 对于电脑本身有多个网卡的时候&#xff0c;选择网卡就成为了一个困惑的地方&#xff0c;其实这里很简单&#xff0c;只要把鼠标放在对应的网卡上面就可以看到地址等信息&#xff0c;就容易判断出来了。 &#xff08;2&#xff09;过滤器 直…...

利用逻辑分析仪解析串口通讯数据

利用逻辑分析仪解析串口通讯数据&#x1f527;采用的是市面上最为广泛使用的USB逻辑分析仪: &#x1f4da;资料下载&#xff1a; 链接: https://pan.baidu.com/s/1c9lwWDbtJxaJED-kzSbiJg 提取码: 5vnr&#x1f528;测试工具为&#xff1a;Logic 2.4.6&#xff0c;也可以使用Pu…...

新整理的前端面试题

pinia和vuex的区别&#xff08;1&#xff09;pinia它没有mutation,他只有state&#xff0c;getters&#xff0c;action【同步、异步】使用他来修改state数据&#xff08;2&#xff09;pinia他默认也是存入内存中&#xff0c;如果需要使用本地存储&#xff0c;在配置上比vuex麻烦…...

数据仓库-数仓分层

层级 全拼 职责划分 ODS(源数据层) Operational DataStore ODS层存储最原始的数据&#xff0c; 对数据不做任何加工处理&#xff1b; 源数据主要来自业务数据库和日志&#xff0c;这些数据是用户操作业务系统产生&#xff0c;所以叫操作型数据(Operational Data) 。 DWD(…...

【Linux】Linux根文件系统扩容

场景&#xff1a;根文件系统需要至少100GB的剩余空间&#xff0c;但是目前就剩余91GB。因此&#xff0c;我们需要对根文件系统进行扩容。# df -h 文件系统 容量 已用 可用 已用% 挂载点 devtmpfs 3.9G 0 3.9G 0% /dev tmpfs …...

RPC编程:Hessian RPC一个老的RPC框架(一)

RPC编程&#xff1a;Hessian RPC一个老的RPC框架一&#xff1a;Hessian RPC1&#xff1a;Hession RPC一个老的RPC框架2&#xff1a;老&#xff0c;为什么还要研究&#xff1f;3&#xff1a;Hession RPC概念二&#xff1a;Hessian RPC设计思想1&#xff1a;Hession依赖于服务器2…...

逆向 x蜂窝 zzzghostsigh

逆向 x蜂窝 zzzghostsigh 版本 9.3.7 新版本是64位的so charles 抓包 目标字段 zzzghostsigh frida java function hook_xPreAuthencode() {Java.perform(function() {var helper Java.use("com.mfw.tnative.AuthorizeHelper");helper.xPreAuthencode.implemen…...

QML 鼠标事件

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 QML 中有一些元素本身是不具备交互能力的(例如:Rectangle、Text、Image 等),那么如何通过鼠标来控制它们的行为呢?这里就需要用到 MouseArea 元素了,它继承于 Item 且不可见,通常需要与可见元素结合使…...

极智项目 | 实战pytorch arcface人脸识别

欢迎关注我的公众号 [极智视界]&#xff0c;获取我的更多经验分享 大家好&#xff0c;我是极智视界&#xff0c;本文介绍 实战pytorch arcface人脸识别&#xff0c;并提供完整项目源码。 本文介绍的实战arcface人脸识别项目&#xff0c;提供完整的可以一键训练、测试的项目工程…...

【IP技术】ipv4和ipv6是什么?

IPv4和IPv6是两种互联网协议&#xff0c;用于在互联网上标识和寻址设备。IPv4&#xff08;Internet Protocol version 4&#xff09;是互联网协议的第四个版本&#xff0c;是当前广泛使用的互联网协议。IPv4地址由32位二进制数构成&#xff0c;通常表示为4个十进制数&#xff0…...

linux基本功系列之uniq命令实战

文章目录前言一. uniq的命令介绍二. 语法格式及常用选项三. 参考案例3.1 统计行数3.2 对文本进行去重3.3 显示不重复的行3.4 仅显示重复的行&#xff0c;且显示重复的行的所有行3.5 忽略字母大小写总结前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓月&#xff0c;本…...

六、SpringBoot项目搭建

日志 Java 主流日志工具库 统一接口 什么是 REST&#xff1f; Representational State Transfer——“表现层状态转化”。可以总结为一句话&#xff1a;REST 是所有 Web 应用都应该遵守的架构设计指导原则。面向资源是 REST 最明显的特征&#xff0c;对于同一个资源的一组不…...

【LeetCode】2363. 合并相似的物品

2363. 合并相似的物品 题目描述 给你两个二维整数数组 items1 和 items2 &#xff0c;表示两个物品集合。每个数组 items 有以下特质&#xff1a; items[i] [valuei, weighti] 其中 valuei 表示第 i 件物品的 价值 &#xff0c;weighti 表示第 i 件物品的 重量 。items 中每…...

华为OD机试题,用 Java 解【出租车计费】问题

最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…...

【人脸识别】DDL:数据分布知识蒸馏思想,提升困难样本(遮挡、低分辨率等)识别效果

论文题目&#xff1a;《Improving Face Recognition from Hard Samples via Distribution Distillation Loss》 论文地址&#xff1a;https://arxiv.org/pdf/2002.03662v3.pdf 代码地址&#xff1a;https://github.com/HuangYG123/DDL 1.前言及相关工作 Large facial variatio…...

如何管理好仓库/库房?

仓库管理是企业管理中不可缺少的一部分&#xff0c;事关企业能否正常运行的关键之一&#xff0c;古人有云&#xff1a;“三军未动粮草先行”&#xff0c;一个企业仓库管理做不好&#xff0c;他的生产管理肯定也是做不好的&#xff0c;不是说生产管理人员的管理能力不具备&#…...

Unity Lighting -- Unity的光源简介

在主菜单栏中&#xff0c;点击Window -> Rendering -> Light Explorer打开光源管理器&#xff0c;这个标签页可以看到场景中所有的光源&#xff0c;包括每个光源的类型&#xff0c;形状&#xff0c;模式&#xff0c;颜色&#xff0c;强度&#xff0c;阴影等信息。 在主菜…...

Android仿网易云音乐歌单详情页

效果图实现思路&#xff1a;1、Activity设置自定义Shared Element切换动画2、透明状态栏&#xff08;透明Toolbar,使背景图上移&#xff09;3、Toolbar底部增加和背景一样的高斯模糊图&#xff0c;并上移图片&#xff08;为了使背景图的底部作为Toolbar的背景&#xff09;4、上…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...