3.【SpringBoot3】文章分类接口开发

序言

在文章分类模块,有以下接口需要开发:

  • 新增文章分类
  • 文章分类列表
  • 获取文章分类详情
  • 更新文章分类
  • 删除文章分类

数据库表字段和实体类属性:

在这里插入图片描述

在数据库表中,create_user 来自于 user 表中的主键 id,是用来记录当前文章分类是哪个用户创建的,有了这个字段,将来用户在查看、修改、删除时就只能操作自己创建的分类。

1. 新增文章分类

需求分析

当用户点击左侧“文章分类”时,会在页面主区域展示文章分类相关内容,页面右上角有“添加分类”按钮,点击该按钮弹出添加分类的弹窗,用户需要输入“分类名称”、“分类别名”,最后点击“确认”以访问后台接口来完成分类的添加。

在这里插入图片描述

接口文档

在这里插入图片描述
在这里插入图片描述

1.1 新增文章分类基本代码编写

接口实现思路

CategoryController 中添加一个用于新增文章分类的 add() 方法:该方法上不添加请求映射路径,因为会在 CategoryController 上添加 “/category”,且方法之间会通过请求方式来区分;add() 方法内部调用 Service 层新增文章分类的方法;Mapper 层编写 SQL 来新增文章分类。

在这里插入图片描述

代码实现

完成代码编写之前,首先新建所需的包、类或接口

在这里插入图片描述

(1) Controller

@RestController
@RequestMapping("/category")
public class CategoryController {@Autowiredprivate CategoryService categoryService;//不添加请求映射路径,方法之间通过请求方式来区分@PostMappingpublic Result add(@RequestBody Category category){categoryService.add(category);return Result.success();}
}

(2) Service

//Service接口
public interface CategoryService {//新增文章分类void add(Category category);
}//Service实现类
@Service
public class CategoryServiceImpl implements CategoryService {@Autowiredprivate CategoryMapper categoryMapper;@Overridepublic void add(Category category) {//完善属性//创建时间、更新时间category.setCreateTime(LocalDateTime.now());category.setUpdateTime(LocalDateTime.now());//创建人idMap<String, Object> map = ThreadLocalUtil.get();Integer id = (Integer) map.get("id");category.setCreateUser(id);categoryMapper.add(category);}
}

(3) Mapper

@Mapper
public interface CategoryMapper {//新增文章分类//不用插入id,数据库会自动生成@Insert("insert into category(category_name, category_alias, create_user, create_time, update_time)" +" values(#{categoryName}, #{categoryAlias}, #{createUser}, #{createTime}, #{updateTime})")void add(Category category);
}

postman 测试:

首先,在文章分类这个集合下配置最新的 token 令牌:

在这里插入图片描述
测试:
在这里插入图片描述
在这里插入图片描述

1.2 新增文章分类参数校验

在上面的代码基础上,如果不填写 categoryName,postman 测试时会报以下错误:

在这里插入图片描述

这里是 Mapper 层报的错误,说明请求已经通过了 Controller 和 Service 层。实际上,如果用户没有传 categoryName,应该在 Controller 层校验时抛出异常,而不是任由请求继续。

接口文档中指出 categoryName、categoryAlias 两个参数不能为空,因此需要对这两个参数进行校验。接口文档中对于这两个参数的说明:

在这里插入图片描述

参照上篇博客【用户模块接口开发】的 4.2 节借助 Validation 完成参数校验:要求字符串类型非空,在成员变量上添加 @NotEmpty 注解即可,另外为了使该注解生效,还要在对应方法参数的前面添加 @Validated 注解。

在这里插入图片描述
在这里插入图片描述

postman 测试:

在这里插入图片描述

2. 展示文章分类列表

需求分析

当用户点击左侧菜单栏中的“文章分类”时,右侧页面主区域会展示出当前用户创建的所有分类,展示这些数据需要调用获取文章分类列表接口来获取。

在这里插入图片描述

接口文档:

在这里插入图片描述

接口实现思路

在 CategoryController 中添加方法 list()。因为展示文章分类列表是查询操作,所以有主体数据响应给浏览器。在接口文档中可以看到,主体数据是一个数组,数组中有多个对象。在 Java 中,数组可以声明为集合 List,结合本节的场景,该 List 中应该有多个 Category 对象代表多个文章分类。所以 Result 类中 data 的类型是 List。
方法内部调用 Service 层,Mapper 层执行响应 SQL。

在这里插入图片描述

代码实现

CategoryController 中:

//文章分类列表查询
@GetMapping
//展示文章分类列表是查询操作,所以有主体数据响应给浏览器
//在接口文档中可以看到,主体数据是一个数组,数组中有多个对象
public Result<List<Category>> list(){List<Category> cs = categoryService.list();return Result.success(cs);
}

CategoryService 中:

//Service接口
//文章分类列表查询
List<Category> list();//Service实现类
//文章分类列表查询
@Override
public List<Category> list() {Map<String, Object> map = ThreadLocalUtil.get();Integer userId = (Integer) map.get("id");return categoryMapper.list(userId);
}

CategoryMapper 中:

//文章分类列表查询
@Select("select * from category where create_user=#{userId}")
List<Category> list(Integer userId);

postman 测试:

在这里插入图片描述

测试成功。但是,现在有个问题,后台返回的数据中,createTime 和 updateTime 的格式与接口文档中的响应数据样例不同。

实体类对象转换成 json 字符串时,如何指定日期的格式呢?需要借助 @JsonFormat 注解。

在这里插入图片描述

此时,响应数据中的日期格式就符合要求了:

在这里插入图片描述

3. 获取文章分类详情

需求分析

在分类列表中,当用户点击某一条分类后面的编辑按钮后,会弹出一个弹窗,弹窗中展示了被点击分类的详细信息,包括分类名称和分类别名。这样,用户就可以在原有信息的基础上进行修改。如果想要展示被点击分类的详细信息,就要访问“获取文章分类详情”接口,拿到数据后再去展示。

在这里插入图片描述
接口文档

在这里插入图片描述

接口实现思路

CategoeyController 中声明 detail() 方法用于获取文章分类详情。从接口文档可知,响应数据中的 data 是一个 Category 对象,所以 detail() 方法返回值是 Result<Category>。该方法上声明一个参数用于接收前端传过来的分类的 id。
方法内部调用 Service 层的方法完成查询,Mapper 层执行相应的 SQL,根据分类的 id 进行查询。

在这里插入图片描述

CategoryController 中:

//获取文章分类详情
@GetMapping("/detail")
public Result<Category> detail(Integer id){//根据点击的文章分类的id进行查询Category category = categoryService.findById(id);return Result.success(category);
}

CategoryService 中:

//根据id查询文章分类信息
Category findById(Integer id);//根据id查询文章分类信息
@Override
public Category findById(Integer id) {Category category = categoryMapper.findById(id);return category;
}

CategoryMapper 中:

//根据id查询文章分类信息
@Select("select * from category where id=#{id}")
Category findById(Integer id);

postman 测试:

在这里插入图片描述

4. 更新文章分类

需求分析

在这里插入图片描述

接口文档

在这里插入图片描述

4.1 更新文章分类基本代码编写

接口实现思路

Controller 层,根据接口文档,需要对 Category 的属性 id、categoryName、categoryAlias 进行参数校验,所以要在参数上添加 @Validated。方法内部调用 Service 层更新头像的方法,Mapper 层编写 SQL 来更新头像。

在这里插入图片描述

CategoryController 中:

//更新文章分类
@PutMapping
public Result update(@RequestBody @Validated Category category){categoryService.update(category);return Result.success();
}

CategoryService 中:

//更新文章分类
void update(Category category);//更新文章分类
@Override
public void update(Category category) {category.setUpdateTime(LocalDateTime.now());categoryMapper.update(category);
}

CategoryMapper 中:

//更新文章分类
@Update("update category set category_name=#{categoryName}, " +"category_alias=#{categoryAlias}, update_time=#{updateTime} " +"where id=#{id}")
void update(Category category);

根据接口文档,需要对 id、categoryName、categoryAlias 进行参数校验:

在这里插入图片描述

postman 测试:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.2 分组校验

完成了前面模块的功能,程序中实际存在一个 bug。在实现“更新文章分类”功能时,我们在 Category 这个实体类的 id 属性上添加了 @NotNull 注解,这就意味着前端在传递数据给添加了 @Validated 注解的 Category 实体参数时,id 不能为空。但是,“新增文章分类”时,前端只需填写 categoryName 和 categoryAlias,无需向后台传递 id(是数据库自动增长的)。因此,虽然“更新文章分类”功能是正常的,但是“新增文章分类”功能却出问题了。

在这里插入图片描述

在这里插入图片描述

只要能将校验分组,新增有一组规则,更新有一组规则,然后在新增接口中使用新增校验规则,更新接口中使用更新校验规则,该问题就能解决。那么,具体该如何实现呢?

  • Validation 中表示分组需要通过接口来表示,定义一个接口就代表一个分组,现在有添加和更新两组,所以首先要在 Category 类中定义两个内部接口;
  • 定义校验项时,指定该校验项的归属分组(groups,类型是数组),可以给同一个校验项指定多个分组;
  • 校验时指定要校验的分组。

在这里插入图片描述
在这里插入图片描述

postman 测试,新增和更新功能都正常:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

当校验分组的组数过多时,挨个向每个注解上的 groups 中添加其隶属的分组是比较麻烦的。此时,可以借助 Validation 的默认分组进行优化。

Validation 的默认分组遵循以下规则:

  • 如果某个校验项没有指定分组,默认属于 Default 分组;
  • 分组之间可以继承,当 A extends B 时,A 就拥有了 B 中所有的校验项。

因此,代码可以优化如下:

在这里插入图片描述

未指定分组的 categoryName 和 categoryAlias 属性属于 Default 分组。既然 Add 分组和 Update 分组都继承了 Default 分组,那么就都包含这两个属性的校验;除此之外,Update 分组还拥有对 id 的校验。因此,将 Add 分组和 Update 分组添加到相应的 @Validated 注解上能够发挥预期作用。

在这里插入图片描述

5. 删除文章分类

接口文档

在这里插入图片描述
代码实现

(1) Controller

//根据id删除文章分类
@DeleteMapping
public Result delete(Integer id){categoryService.delete(id);return Result.success();
}

(2) Service

//根据id删除文章分类
void delete(Integer id);//根据id删除文章分类
@Override
public void delete(Integer id) {categoryMapper.delete(id);
}

(3) Mapper

//根据id删除文章分类
@Delete("delete from category where id=#{id}")
void delete(Integer id);

postman 测试:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

JDK8新特性(一)集合之 Stream 流式操作

1.Stream流由来 首先我们应该知道&#xff1a;Stream流的出现&#xff0c;主要是用在集合的操作上。在我们日常的工作中&#xff0c;经常需要对集合中的元素进行相关操作。诸如&#xff1a;增加、删除、获取元素、遍历。 最典型的就是集合遍历了。接下来我们先举个例子来看看 J…

MYSQL之索引语法与使用

索引分类 分类 含义 特点 关键字 主键索引 针对表中主键创建的索引 默认自动创建&#xff0c;只能有一个 PRIMARY 唯一索引 …

Gateway+Springsecurity+OAuth2.0+JWT 实现分布式统一认证授权!

目录 1. OAuth2.0授权服务 2. 资源服务 3. Gateway网关 4. 测试 在SpringSecurityOAuth2.0 搭建认证中心和资源服务中心-CSDN博客 ​​​​​​ 基础上整合网关和JWT实现分布式统一认证授权。 大致流程如下&#xff1a; 1、客户端发出请求给网关获取令牌 2、网关收到请求…

Golang 中如何实现 Set

在Go编程中&#xff0c;数据结构的选择对解决问题至关重要。本文将探讨如何在 GO 中实现 set 和 bitset 两种数据结构&#xff0c;以及它们在Go中的应用场景。 Go 的数据结构 Go 内置的数据结构并不多。工作中&#xff0c;我们最常用的两种数据结构分别是 slice 和 map&#…

K8S--安装Nginx

原文网址&#xff1a;K8S--安装Nginx-CSDN博客 简介 本文介绍K8S安装Nginx的方法。 1.创建Nginx目录及配置文件 mkdir -p /work/devops/k8s/app/nginx/{config,html} 在config目录下创建nginx.conf配置文件&#xff0c;内容如下&#xff1a; # events必须要有 events {wo…

jdk的安装和Tomcat的安装

jdk的安装 双击jdk&#xff0c;然后一路下一步 公共JRE可以关闭&#xff0c;没多大用&#xff0c;反而会占用内存 计算机–>属性–>高级系统设置–>环境变量 系统变量–新建 JAVA_HOMEjdk的存放路径 修改path 在path的最后面添加&#xff08;&#xff1b;%JAVA_H…

即插即用篇 | UniRepLKNet:用于音频、视频、点云、时间序列和图像识别的通用感知大卷积神经网络 | DRepConv

大卷积神经网络(ConvNets)近来受到了广泛研究关注,但存在两个未解决且需要进一步研究的关键问题。1)现有大卷积神经网络的架构主要遵循传统ConvNets或变压器的设计原则,而针对大卷积神经网络的架构设计仍未得到解决。2)随着变压器在多个领域的主导地位,有待研究ConvNets…

【漏洞复现】SpringBlade export-user接口SQL注入漏洞

文章目录 前言声明一、SpringBlade系统简介二、漏洞描述三、影响版本四、漏洞复现五、修复建议 前言 SpringBlade 是一个由商业级项目升级优化而来的微服务架构 采用Spring Boot 2.7 、Spring Cloud 2021 等核心技术构建&#xff0c;完全遵循阿里巴巴编码规范。提供基于React和…

PowerShell install 一键部署grafana

grafana 前言 Grafana 是一款开源的数据可视化和监控仪表盘工具。它提供了丰富的数据查询、可视化和报警功能,可用于实时监控、数据分析和故障排除等领域。 通过 Grafana,您可以连接到各种不同的数据源,包括时序数据库(如 Prometheus、InfluxDB)和关系型数据库(如 MySQ…

Halcon基于形状的模板匹配inspect_shape_model

Halcon基于形状的模板匹配 基于形状的匹配&#xff0c;就是使用目标对象的轮廓形状来描述模板。Halcon中有操作助手&#xff0c;可以直观 地进行形状模板匹配的参数选择以及效果测试。如果使用算子编写&#xff0c;步骤如下。 &#xff08;1&#xff09;从参考图像上选择检测的…

c++:string相关的oj题(415. 字符串相加、125. 验证回文串、541. 反转字符串 II、557. 反转字符串中的单词 III)

文章目录 1. 415. 字符串相加题目详情代码1思路1代码2思路2 2. 125. 验证回文串题目详情代码1&#xff08;按照要求修改后放到新string里&#xff09;思路1代码2(利用双指针/索引)思路2 3. 541. 反转字符串 II题目详情代码1思路1 4. 557. 反转字符串中的单词 III题目详情代码1&…

CocoaPods的安装和使用

前言 本篇文章讲述CocoaPods的安装和使用 安装cocoaPods 如果电脑没有安装过cocoaPods&#xff0c;需要先安装&#xff0c;使用下面的命令&#xff1a; sudo gem install cocoapods输入密码后开始安装&#xff0c;需要等待。。。但是我这里报错了。 The last version of d…

nexus清理docker私库

下载nexus-cli客户端&#xff0c;并非必须下载到服务器&#xff0c;理论上只要能访问到nexus就行 wget https://s3.eu-west-2.amazonaws.com/nexus-cli/1.0.0-beta/linux/nexus-cli这个链接下载不了了&#xff0c;末尾有资源下载&#xff0c;里面包含了完整包和脚本&#xff0…

即插即用篇 | YOLOv8 引入 SENetv2 | 多套版本配合使用

卷积神经网络(CNNs)通过提取空间特征并在基于视觉的任务中实现了最先进的准确性,彻底改变了图像分类。所提出的压缩激励网络模块收集输入的通道表示。多层感知机(MLP)从数据中学习全局表示,在大多数用于学习图像提取特征的图像分类模型中起到关键作用。在本文中,我们引入…

npm ,yarn 更换使用国内镜像源,阿里源,清华大学源

在平时开发当中&#xff0c;我们经常会使用 Npm&#xff0c;yarn 来构建 web 项目。但是npm默认的源的服务器是在国外的&#xff0c;如果没有梯子的话。会感觉特别特别慢&#xff0c;所以&#xff0c;使用国内的源是非常有必要的。 Nnpm&#xff0c; yarn 常用命令 常用命令&am…

Appium 环境配置

Appium 是一个开源的、跨平台的测试框架&#xff0c;可以用来测试 Native App、混合应用、移动 Web 应用&#xff08;H5 应用&#xff09;等&#xff0c;也是当下互联网企业实现移动自动化测试的重要工具。Appium 坚持的测试理念&#xff1a; •无需用户对 App 进行任何修改或…

opencv#27模板匹配

图像模板匹配原理 例如给定一张图片&#xff0c;如上图大矩阵所示&#xff0c;然后给定一张模板图像&#xff0c;如上图小矩阵。 我们在大图像中去搜索与小图像中相同的部分或者是最为相似的内容。比如我们在图像中以灰色区域给出一个与模板图像尺寸大小一致的区域&#xff0c;…

软考系分之计算机网络规划设计、综合布线、RAID和网络存储等

文章目录 1、概要2、网络的三层模型3、综合布线系统4、廉价磁盘冗余阵列&#xff08;RAID&#xff09;5、网络存储6、总结 1、概要 本篇重点介绍计算机网络中的网络规划设计、综合布线、RAID和网络存储。 2、网络的三层模型 三层模型分为核心层、汇聚层和接入层&#xff0c;接…

数组A[m+n]中存放了两个线性表(a1,a2,.....am)和(b1,b2.....bn),将数组中的两个线性表的位置互换,要求空间复杂度为1

要求空间复杂度为O(1)&#xff0c;那么不可以借助辅助数组来完成此操作 算法思路&#xff1a;可先将此数组逆置变成bn,......b1,am,....,a1&#xff0c;然后分别逆转两个线性表的数据元素 算法实现 1、定义一个函数&#xff0c;该函数的功能是可以对一个数组的任意连续的部分进…

UDP和TCP代理协议有什么区别?哪个更好

在互联网的世界里&#xff0c;数据传输的方式有很多种&#xff0c;其中 UDP 和 TCP 是两种常见的传输协议。而代理协议则是为了在网络中传输数据时提供安全、稳定和高效的传输环境。那么&#xff0c;UDP 和 TCP 代理协议有什么区别呢&#xff1f;哪个更好呢&#xff1f;接下来&…