springboot3项目练习详细步骤(第二部分:文章分类模块)

news2024/11/23 7:33:25

 

新增文章分类

接口文档

业务实现

参数校验

文章分类列表

接口文档

业务实现 

获取文章分类详情

接口文档 

业务实现

更新文章分类

接口文档 

业务实现

分组校验

问题

概念 

实现步骤

总结

删除文章分类

接口文档

业务实现 


该模块大部分请求的路径相同,接口功能区分方式按请求方式不同而进行区分 

文章分类业务表结构

 新增文章分类

 接口文档

 业务实现

 创建CategoryController控制类并编写实现方法

@RestController //定义为控制类
@RequestMapping("/category") //设置请求映射路径
public class CategoryController {
    @Autowired
    private CategoryService categoryService; //注入CategoryService

    @PostMapping
    public Result add(@RequestBody Category category){
        categoryService.add(category);
        return Result.success();
    }
}

 创建CategoryService接口并添加抽象方法

void add(Category category);

创建CategoryServiceimpl接口实现类

@Service
public class CategoryServiceimpl implements CategoryService {
    @Autowired
    private CategoryMapper categoryMapper; //注入CategoryMapper接口

    @Override
    public void add(Category category) {
        //补充添加id属性值
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");

        category.setCreateUser(id);

        categoryMapper.add(category);
        Result.success();
    }
}

 创建CategoryMapper接口用于操作mybatis

@Mapper
public interface CategoryMapper {
    //新增
    @Insert("insert into category(category_name,category_alias,create_user,create_time,update_time)" +
            "values(#{categoryName},#{categoryAlias},#{createUser},now(),now()) ")
    void add(Category category);
}

运行请求查看

 数据库中已成功添加该记录

参数校验

用到上一篇讲到的对实体对象变量进行参数校验必须要传入有效参数

 

文章分类列表

 接口文档

业务实现 

编写CategoryController中的请求的方法

    @GetMapping
    public Result<List<Category>> list(){
        List<Category> cs = categoryService.list();
        return Result.success(cs);
    }

编写CategoryService接口抽象方法

    //列表
    List<Category> list();

编写CategoryServiceimpl接口实现类的方法

    @Override
    public List<Category> list() {
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");

        return categoryMapper.list(id);
    }

编写CategoryMapper接口的方法

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

 运行请求查看

 发现返回的日期格式有问题,需要转换一下

在实体类日期属性变量上使用@JsonFormat注解用于指定日期格式

重新运行项目再请求查看日期格式已指定好了

 

获取文章分类详情

接口文档 

业务实现

编写CategoryController中的请求的方法

    @GetMapping("/detail")
    public Result<Category> detail(){
        Category c = categoryService.findById();
        return Result.success(c);
    }

编写CategoryService接口抽象方法

    //根据id查询信息
    Category findById(Integer id);

编写CategoryServiceimpl接口实现类的方法

    @Override
    public Category findById(Integer id) {
        Category c =categoryMapper.findById(id);
        return c;
    }

编写CategoryMapper接口的方法

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

运行请求查看

 

更新文章分类

接口文档 

业务实现

在实体类中对id成员变量加上注解进行参数校验 

编写CategoryController中的请求的方法

    @PutMapping
    public Result update(@RequestBody @Validated Category category){
        categoryService.update(category);
        return Result.success();
    }

编写CategoryService接口抽象方法

    //更新分类
    void update(Category category);

编写CategoryServiceimpl接口实现类的方法

    @Override
    public void update(Category category) {
        categoryMapper.update(category);
    }

编写CategoryMapper接口的方法

    //更新分类
    @Select("update category set category_name=#{categoryName},category_alias=#{categoryAlias},update_time=now() where id=#{id}")
    void update(Category category);

运行请求查看

 

分组校验

问题

对实体成员变量进行参数校验时,不同的请求参数类型和需要的参数数量不同,如果按照其中一个接口的规范写死那么另一个接口所需的类型参数就会冲突导致不通过。所以需要对不同的接口单独定义参数校验 

概念 

  • 把校验项进行归类分组,在完成不同的功能的时候,校验指定组中的校验项
  • 定义分组
  • 定义校验项时指定归属的分组
  • 校验时指定要校验的分组

实现步骤

对添加文章和更新文章进行参数分组校验

在实体类中定义内部接口

对成员变量指定校验项分组

 在接口方法传参时对属性指定分组

这样就分组好了,然后请求参数也不会互相影响。 

 

总结

  1. 在实体类内部定义接口来定义分组
  2. 通过groups属性指定对校验项分组
  3. 给@Validated注解的value属性赋值用于指定分组
  4. 校验项默认属于Default分组
  5. 定义校验项时如果没有指定分组,则属于Default分组,分组可以继承

删除文章分类

接口文档

业务实现 

编写CategoryController中的请求的方法

    @DeleteMapping
    public Result delete(Integer id){
        categoryService.delete(id);
        return Result.success();
    }

编写CategoryService接口抽象方法

    //删除分类
    void delete(Integer id);

编写CategoryServiceimpl接口实现类的方法

    @Override
    public void delete(Integer id) {
        categoryMapper.delete(id);
    }

编写CategoryMapper接口的方法

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

运行请求查看

 数据库中已成功删除

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

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

相关文章

使用gird布局实现表格(解决边框重叠问题)

<div class"quickInput"><div class"quickInputTable"><span class"quickInputTitleStyle">余额快捷输入 (单位&#xff1a;元)</span><div class"box"><div class"btn1" v-for"num …

栈数据结构

1,概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈(push)&#x…

Python爬虫教程:入门爬取网页数据

1.遵守法律法规 爬虫在获取网页数据时&#xff0c;需要遵守以下几点&#xff0c;以确保不违反法律法规&#xff1a; 不得侵犯网站的知识产权&#xff1a;爬虫不得未经授权&#xff0c;获取和复制网站的内容&#xff0c;这包括文本、图片、音频、视频等。 不得违反网站的使用条…

我独自升级崛起下载方法分享 下载教程

《我独自升级&#xff1a;崛起》这款精彩绝伦的动作角色扮演游戏&#xff0c;灵感来源于大热网络漫画&#xff0c;让玩家亲自踏上主角程肖宇的征途&#xff0c;从觉醒初阶到实力飞跃&#xff0c;每一步成长都扣人心弦。值得注意的是&#xff0c;尽管全球正式发布日期定在了五月…

雷军-2022.8小米创业思考-6-互联网七字诀之专注:有所为,有所不为;克制贪婪,少就是多;一次解决一个最迫切的需求

第六章 互联网七字诀 专注、极致、口碑、快&#xff0c;这就是我总结的互联网七字诀&#xff0c;也是我对互联网思维的高度概括。 专注 从商业角度看&#xff0c;专注就是要“把鸡蛋尽量放在一个篮子里”。这听起来似乎有些不合理&#xff0c;大家的第一反应可能是“风险会不会…

符号数学库-sympy

文章目录 前言一、符号声明二、代数运算三、求解方程和方程组1 求解一元方程2 求解方程组四、微积分(求导(包括偏导)求积分等)1 求导(偏导)2 求不定积分与定积分五、解微分方程与微分方程组1 解微分方程2 解微分方程组下面我们玩个有意思的,机器学习中的损失函数总结前言…

PHP基于vscode医院安全不良事件管理系统源码(AEMS)前端vue2+element+后端laravel8不良事件上报与闭环管理

PHP基于vscode医院安全不良事件管理系统源码&#xff08;AEMS&#xff09;前端vue2element后端laravel8不良事件上报与闭环管理 医院不良事件上报与管理系统结合现代医院管理思路&#xff0c;遵照PDCA全面质量循环管理方法而设计&#xff0c;并在多家大型三甲医院成熟运用。系统…

快速找出存(不存在)在某个(或多个)文件的文件夹

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 想要找出有下面这个文件存在的文件夹 切换到批量文件复制版块&#xff0c;快捷键Ctrl5 右侧&#xff0c;搜索添加 选定范围&#xff0c;勾选搜索文件夹、包…

Go 语言基础之面向对象编程

1、OOP 首先&#xff0c;Go 语言并不是面向对象的语言&#xff0c;只是可以通过一些方法来模拟面向对象。 1.1、封装 Go 语言是通过结构体&#xff08;struct&#xff09;来实现封装的。 1.2、继承 继承主要由下面这三种方式实现&#xff1a; 1.2.1、嵌套匿名字段 //Add…

RISCV 外部GCC 工具链安装@FreeBSD15

在交叉编译的时候&#xff0c;可以使用FreeBSD15默认的工具链&#xff1a;LLVM 也可以使用GCC工具链&#xff0c;GCC可以使用现成pkg包安装&#xff0c;也可以编译安装。 LLVM的特点是高移植性和高效&#xff0c;但学习成本高。GCC的特点是成熟稳定&#xff0c;但优化能力有限…

多线程系列(七) -ThreadLocal 用法及内存泄露分析

一、简介 在 Java web 项目中&#xff0c;想必很多的同学对ThreadLocal这个类并不陌生&#xff0c;它最常用的应用场景就是用来做对象的跨层传递&#xff0c;避免多次传递&#xff0c;打破层次之间的约束。 比如下面这个HttpServletRequest参数传递的简单例子&#xff01; p…

机器学习项目实践-基础知识部分

环境建立 我们做项目第一步就是单独创建一个python环境&#xff0c;Python新的隔离环境 创建&#xff1a;python -m venv ml 使用&#xff1a;.\Scripts\activate python -m venv ml 是在创建一个名为 ml 的虚拟环境&#xff0c;这样系统会自动创建一个文件夹ml&#xff0c;…

[redis] 说一说 redis 的底层数据结构

Redis有动态字符串(sds)、链表(list)、字典(ht)、跳跃表(skiplist)、整数集合(intset)、压缩列表(ziplist) 等底层数据结构。 Redis并没有使用这些数据结构来直接实现键值对数据库&#xff0c;而是基于这些数据结构创建了一个对象系统&#xff0c;来表示所有的key-value。 文章…

鸿蒙编译子系统详解(二)main.py

1.5.4源码解析 1.5.4.1 build/hb/main.py脚本 这个脚本是编译的主程序脚本&#xff0c;流程如下&#xff1a; 首先是初始化各种module类&#xff0c;然后运行对应模块。 hb分为build,set,env,clean,tool,help几个模块&#xff0c;模块源码位于build/hb/modules/目录下&#xff…

安卓开发(二)Android开发基础知识

了解Android Android大致可以分为4层架构&#xff1a;Linux内核层、系统运行库层、应用框架层和应用层。 内核层&#xff1a;Android系统是基于Linux内核的&#xff0c;这一层为Android设备的各种硬件提供了底层的驱动&#xff0c;如显示驱动、音频驱动、照相机驱动、蓝牙驱动…

MS2107 宏晶微 音视频采集芯片 提供开发资料

1. 基本介绍 MS2107 是一款视频和音频采集芯片,内部集成 USB2.0 控制器和数据收发模块、视频 ADC模块、音频 ADC 模块和音视频处理模块。MS2107可以将 CVBS、S-Video 和音频信号通过 USB接口传送到 PC、智能手机和平板电脑上预览或采集。MS2107 输出支持 YUV422 和 MJPEG 两种…

Python基础详解二

一&#xff0c;函数 函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现某个功能的代码段 def myMethod(data):print("数据长度为",len(data))myMethod("dsdsdsds") 函数的定义&#xff1a; def 函数名(传入参数):函数体return 返回值 def m…

MahApps.Metro的MVVM模式介绍(一)

MahApps.Metro是一个开源的WPF (Windows Presentation Foundation) UI 控件库。它的特点有现代化设计、主题定制、响应式布局、内置控件。 而Mvvm模式的核心思想是将用户界面&#xff08;View&#xff09;与应用程序逻辑&#xff08;ViewModel&#xff09;分离&#xff0c;以实…

软件架构的艺术:探索演化之路上的18大黄金原则

实际工作表明&#xff0c;一步到位的设计往往不切实际&#xff0c;而演化原则指导我们逐步优化架构&#xff0c;以灵活响应业务和技术的变化。这不仅降低了技术债务和重构风险&#xff0c;还确保了软件的稳定性和可扩展性。同时&#xff0c;架构的持续演进促进了团队协作&#…

C语言例题35、反向输出字符串(指针方式),例如:输入abcde,输出edcba

#include <stdio.h>void reverse(char *p) {int len 0;while (*p ! \0) { //取得字符串长度p;len;}while (len > 0) { //反向打印到终端printf("%c", *--p);len--;} }int main() {char s[255];printf("请输入一个字符串&#xff1a;");gets(s)…