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 {
    @Autowired
    private CategoryService categoryService;
    //不添加请求映射路径,方法之间通过请求方式来区分
    @PostMapping
    public 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 {
    @Autowired
    private CategoryMapper categoryMapper;
    @Override
    public void add(Category category) {
        //完善属性
        //创建时间、更新时间
        category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());
        //创建人id
        Map<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 测试:

在这里插入图片描述

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用AFPN渐近特征金字塔网络优化YOLOv8改进小目标检测效果(不适合新手)

目录 简单概述 算法概述 优化效果 参考文献 文献地址&#xff1a;paper 废话少说&#xff0c;上demo源码链接&#xff1a; 简单概述 AFPN的核心思想&#xff1a;AFPN主要通过引入渐近的特征融合策略&#xff0c;逐步整合底层、高层和顶层的特征到目标检测过程中。这种融合…

正信晟锦:亲戚借了钱怎么要回来

亲戚间的金钱借贷&#xff0c;往往是情感与金钱交织的微妙话题。在中国传统文化中&#xff0c;家族关系至关重要&#xff0c;因此处理此类事宜时需要格外细致和谨慎。要回借出的钱&#xff0c;不仅要考虑到资金的回流&#xff0c;更要维护和谐的家庭关系。 沟通是解决问题的关键…

v-for中使用v-model的坑点

问题场景: 有这样一种场景,比如我们需要根据数据创建多个input输入框 <template><div v-for"(item, index) in list" :key"index"><a-input v-model"item"></a-input></div></template><script>expo…

Git--创建仓库(1)

git init Git 使用 git init 命令来初始化一个 Git 仓库&#xff0c;Git 的很多命令都需要在 Git 的仓库中运行&#xff0c;所以 git init 是使用 Git 的第一个命令。 在执行完成 git init 命令后&#xff0c;Git 仓库会生成一个 .git 目录&#xff0c;该目录包含了资源的所有…

别再局限于Android和iOS了尝试鸿蒙APP系统开发吧!

最近&#xff0c;多家互联网公司也发布了鸿蒙OS的App开发工程师的岗位&#xff0c;开启了抢人大战&#xff0c;有的企业开出了近百万的年薪招聘鸿蒙OS工程师&#xff0c;而华为甚至为鸿蒙OS资深架构师开出了100万元—160万元的年薪。 「纯血」鸿蒙开启&#xff0c;欲与 Andori…

css clip-path

1 解释 clip-path 属性使用裁剪方式创建元素的可显示区域。区域内的部分显示&#xff0c;区域外的隐藏。浏览器会裁剪掉裁剪区域以外的内容&#xff0c;包括: 背景&#xff0c;内容&#xff0c;边框&#xff0c;阴影等&#xff0c;另外也不会捕获裁剪区域之外的hover click等事…

《JavaScript权威指南》读书笔记1

服创要开始了&#xff0c;选题基本上都是关于ai的&#xff0c;之前写的项目没有和ai有关的&#xff0c;也没有学习过这方面的知识。现在我们组基本上确认的选题是&#xff1a;【A01】基于文心大模型的智能阅卷平台设计与开发【百度】【A01】基于文心大模型的智能阅卷平台设计与…

用 AI 定制龙年红包封面保姆级教程

作者&#xff1a;苍何&#xff0c;前大厂高级 Java 工程师&#xff0c;阿里云专家博主&#xff0c;CSDN 2023 年 实力新星&#xff0c;土木转码&#xff0c;现任部门技术 leader&#xff0c;专注于互联网技术分享&#xff0c;职场经验分享。 &#x1f525;热门文章推荐&#xf…

代码中遇到的问题2

目录 记录: 好处&#xff1a; 问题一&#xff1a; 解答: 问题二: 解答: 常见类型问题: 记录: string connStr ConfigurationManager.ConnectionStrings["connStr"].ConnectionString; 在代码中写上这段代码&#xff0c;将连接数据库的代码语句放到&#xff…

算法练习-替换数字(思路+流程图+代码)

难度参考 难度&#xff1a;简单 分类&#xff1a;字符串 难度与分类由我所参与的培训课程提供&#xff0c;但需要注意的是&#xff0c;难度与分类仅供参考。以下内容均为个人笔记&#xff0c;旨在督促自己认真学习。 题目 给定一个字符串S,它包含小写字母和数字字符&#xff0…

【GitHub项目推荐--开源2D 游戏引擎】【转载】

microStudio 是一个可在浏览器中运行的游戏引擎&#xff0c;它拥有一套精美、设计精良、全面的工具&#xff0c;可以非常轻松地帮助你创建 2D 游戏。 你可以在浏览器中访问 microStudio.dev 开始搭建你的游戏&#xff0c;当然你可以克隆现有项目或创建新游戏并开始编码&#x…

Go 基本数据

第 2 章 基本数据类型 Go 的数值类型包括了不同大小的整数 、浮点数 、复数&#xff1b; 各种数值类型分别有自己的大小&#xff0c;对正负号支持也各不相同&#xff1b; 1. 整数&#xff08;OK&#xff09; 整数类型&#xff08;整型&#xff09;整数类型Go 语言同时支持 有…

代码随想录算法训练营29期|day28 任务以及具体安排

93.复原IP地址 class Solution {List<String> result new ArrayList<>();public List<String> restoreIpAddresses(String s) {StringBuilder sb new StringBuilder(s);backTracking(sb, 0, 0);return result;}private void backTracking(StringBuilder s,…

VS Code Json格式化插件-JSON formatter

&#x1f9aa;整个文件格式化 按快捷键Shift Alt F &#x1f96a;仅格式化选择内容 需要选择完整的json段落即&#xff1a;{} 或 [] 括起来的部分&#xff0c;再按快捷键Ctrl K F

高分辨率图像合成;可控运动合成;虚拟试衣;在FPGA上高效运行二值Transformer

本文首发于公众号&#xff1a;机器感知 高分辨率图像合成&#xff1b;可控运动合成&#xff1b;虚拟试衣&#xff1b;在FPGA上高效运行二值Transformer Scalable High-Resolution Pixel-Space Image Synthesis with Hourglass Diffusion Transformers We present the Hourgla…

蓝桥杯真题(Python)每日练Day4

题目 OJ编号2117 题目分析 第一种先采用暴力的思想&#xff0c;从第一根竹子开始&#xff0c;找到连续的高度相同的竹子&#xff0c;砍掉这些竹子&#xff0c;一直循环这个方法&#xff0c;直到所有的竹子高度都为1。很明显&#xff0c;依次遍历竹子的高度复杂度为O&#x…

jdk的安装和Tomcat的安装

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

SpringBoot整合SSE

目录 1.SseController2. SseServiceSseServiceSseServiceImpl 3.SendMessageTask4.将定时任务加入启动类5.参考资料 1.SseController Slf4j RestController RequestMapping("sse") public class SseController {Autowiredprivate SseService sseService;RequestMappi…

cesium应用篇:静态图添加与平移、缩放

应用说明 添加静态图到指定extent通过键盘事件对static image进行调整 向东、西、南、北移动沿东西、南北方向缩放命令行侧输出当前extent&#xff0c;可用于几何匹配 初始化 Earth 初始化 <!DOCTYPE html> <html lang"en"> <head><meta c…

openai assistants api接入微信机器人,实现类GPTs功能

chatgpt网址:https://chat.xutongbao.top 比普通gpt多了代码解释器功能&#xff0c;和上传训练数据文件的功能&#xff0c;这两个功能就是GPTs拥有的&#xff0c;而普通gpt没有拥有的