springboot3项目练习详细步骤(第三部分:文章管理模块)
目录
发布文章
接口文档
业务实现
自定义参数校验
项目参数要求
实现思路
实现步骤
文章列表(条件分页)
接口文档
业务实现
mapper映射
更新文章
接口文档
业务实现
获取文章详情
接口文档
业务实现
删除文章
接口文档
业务实现
文章管理业务表结构

发布文章

接口文档



业务实现
创建ArticleController类并完成请求的方法

@RestController
@RequestMapping("/article")
public class ArticleController {@Autowiredprivate ArticleService articleService; //注入ArticleService接口@PostMappingpublic Result add(@RequestBody Article article){articleService.add(article);return Result.success();}
}
创建ArticleService接口并完成方法
public interface ArticleService {//新增文章void add(Article article);
}
创建ArticleServiceimpl接口实现类并完成方法

@Service
public class ArticleServiceimpl implements ArticleService {@Autowiredprivate ArticleMapper articleMapper; //注入ArticleMapper接口@Overridepublic void add(Article article) {//补充id属性值 用于添加到create_usera字段中Map<String,Object> map = ThreadLocalUtil.get();Integer id = (Integer) map.get("id");article.setCreateUser(id);articleMapper.add(article);}
}
创建ArticleMapper接口并完成方法

@Mapper
public interface ArticleMapper {//添加文章@Insert("insert into article(title,content,cover_img,state,category_id,create_user,create_time,update_time)" +" values(#{title},#{content},#{coverImg},#{state},#{categoryId},#{createUser},now(),now())")void add(Article article);
}
运行请求查看


数据库中查看已添加成功

自定义参数校验
已有的注解不能满足所有的校验需求,特殊的情况需要自定义校验(自定义校验注解)
项目参数要求

实现思路
- 自定义注解State
- 自定义校验数据的类StateValidation 实现ConstraintValidator接口
- 在需要校验的地方使用自定义注解
实现步骤
在Article实体类中对能满足校验要求的成员变量进行校验

在ArticleController接口中对方法参数使用@Validated注解

但对于state变量参数已有的注解不能满足所有的校验需求,所以需要对其使用自定义参数校验。
新建anno包,在包下新定义State注解,并完善定义注解的代码

@Documented //元注解 用于抽取自定义的注解到帮助文档
@Target({ElementType.FIELD}) //元注解 自定义的标注用在哪些地方 FIELD表示在变量属性上标注
@Retention(RetentionPolicy.RUNTIME) //元注解 用于标识自定义的注解会在哪一阶段保留 RUNTIME表示运行阶段
@Constraint(validatedBy = {}) //用于指定谁给自定义的注解定义参数校验规则
public @interface State {//message用于提供校验失败后的提示信息String message() default "'state参数的值只能是已发布或者草稿";//用于指定分组Class<?>[] groups() default {};//负载 获取到State注解的附如信息Class<? extends Payload>[] payload() default {};
}
新建validation包,在包下定义StateValidation校验规则类,并完善校验规则代码

public class StateValidation implements ConstraintValidator<State,String> { //接口的泛型:<会给哪个注解提供校验规则,校验的数据类型>/***参数解释:** value:将来要校验的数据* context* return: 如果返回false则校验不通过, 如果返回true则校验通过*/@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {//提供校验规则if(value == null){return false;}if(value.equals("已发布") || value.equals("草稿")){return true;}return false; //其余情况返回false}
}
再回到State注解中完善要指定的校验规则

到实体类中在需要的成员变量使用该自定义注解用于达到注解参数校验的目的

文章列表(条件分页)

接口文档





业务实现
创建PageBean实体类

//分页返回结果对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean <T>{private Long total;//总条数private List<T> items;//当前页数据集合
}
编写ArticleController中的请求的方法

@GetMappingpublic Result<PageBean<Article>> list(Integer pageNum,Integer pageSize, //使用@RequestParam(required = false)可以使参数设置为可传入也可不传入@RequestParam(required = false) String categoryId,@RequestParam(required = false) String state){PageBean<Article> pb = articleService.list(pageNum,pageSize,categoryId,state);return Result.success(pb);}
编写ArticleService接口的方法
//条件分页列表查询PageBean<Article> list(Integer pageNum, Integer pageSize, String categoryId, String state);
}
在pom文件导入pagehelper插件依赖用于完成分页查询
<!-- pagehelper插件--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.6</version></dependency>
编写ArticleServiceimpl接口实现类的方法

@Overridepublic PageBean<Article> list(Integer pageNum, Integer pageSize, String categoryId, String state) {//定义pageBean对象PageBean<Article> pb = new PageBean<>();//开启分页查询 PageHelperPageHelper.startPage(pageNum,pageSize);//添加id参数 调用mapper接口的方法Map<String,Object> map = ThreadLocalUtil.get();Integer id = (Integer) map.get("id");List<Article> arlist = articleMapper.list(id,categoryId,state);//page中提供了方法可以获取pagehelper分页查询后,得到的总记录条数和当前页数Page<Article> p = (Page<Article>) arlist;//将page对象获取的记录和条数添加到pagebean对象中pb.setTotal(p.getTotal());pb.setItems(p.getResult());return pb; //返回pagebean对象}
编写ArticleMapper接口的方法
//条件分页列表查询List<Article> list(Integer id, String categoryId, String state);
mapper映射
由于参数 categoryId和state参数为非必填,所以这里sql需要用到sql映射文件来写动态sql
在resource目录下创建和mapper包一样的结构目录

目录结构要和mapper接口目录相同

配置文件名称要和接口名称相同
编写sql映射配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 命名空间要和mapper接口的路径全类名要相同 -->
<mapper namespace="com.springboot.springboot_test.mapper.ArticleMapper">
<!-- 编写动态sql
select标签的
id参数要和mapper接口的方法名称一致
resultType 返回值类型要和实体类名称一致--><select id="list" resultType="com.springboot.springboot_test.pojo.Article">select * from article<where><if test="categoryId != null">category_id = #{categoryId}</if><if test="state != null">and state = #{state}</if>and create_user= #{id}</where></select></mapper>
运行请求查看


更新文章
接口文档




业务实现
编写ArticleController中的请求的方法
@PutMappingpublic Result update(@RequestBody @Validated Article article){articleService.update(article);return Result.success();}
编写ArticleService接口的方法
//更新文章void update(Article article);
编写ArticleServiceimpl接口实现类的方法
@Overridepublic void update(Article article) {articleMapper.update(article);}
编写ArticleMapper接口的方法
//更新文章@Update("update article set title = #{title},content = #{content},cover_img = #{coverImg},state = #{state}, " +"category_id = #{categoryId},update_time = now() where id = #{id}")void update(Article article);
运行请求查看



获取文章详情
接口文档



业务实现
编写ArticleController中的请求的方法
@GetMapping("/detail")public Result detail(Integer id){Article ar = articleService.findById(id);return Result.success(ar);}
编写ArticleService接口的方法
//查看文章详情Article findById(Integer id);
编写ArticleServiceimpl接口实现类的方法
@Overridepublic Article findById(Integer id) {Article ar = articleMapper.findById(id);return ar;}
编写ArticleMapper接口的方法
//查看文章详情@Select("select * from article where id =#{id}")Article findById(Integer id);
运行请求查看


删除文章
接口文档



业务实现
编写ArticleController中的请求的方法
@DeleteMappingpublic Result delete(Integer id){articleService.delete(id);return Result.success();}
编写ArticleService接口的方法
//删除文章void delete(Integer id);
编写ArticleServiceimpl接口实现类的方法
@Overridepublic void delete(Integer id) {articleMapper.delete(id);}
编写ArticleMapper接口的方法
//删除文章@Delete("delete from article where id = #{id}")void delete(Integer id);
运行请求查看


相关文章:
springboot3项目练习详细步骤(第三部分:文章管理模块)
目录 发布文章 接口文档 业务实现 自定义参数校验 项目参数要求 实现思路 实现步骤 文章列表(条件分页) 接口文档 业务实现 mapper映射 更新文章 接口文档 业务实现 获取文章详情 接口文档 业务实现 删除文章 接口文档 业务实现 文章管理业务表结构…...
【面试八股总结】C++11新特性:智能指针
参考资料 :阿秀、代码随想录 智能指针是一个类,用于存储指向动态分配对象的指针,负责自动释放动态分配的对象,防止堆内存泄露。动态分配的资源,交给一个类对象去管理,当类对象声明周期结束时,自…...
【教程向】从零开始创建浏览器插件(二)深入理解 Chrome 扩展的 manifest.json 配置文件
第二步:深入理解 Chrome 扩展的 manifest.json 配置文件 上一次我们已经着手完成了一个自己的浏览器插件,链接在这里:我是链接 在本篇博客中,我们将更详细地探讨 Chrome 扩展中的 manifest.json 文件。这个文件是每个浏览器扩展…...
美易官方:美国房地产贷款逾期率飙升,银行业危机仍可控?现货黄金暂守2360
美国房地产贷款逾期率飙升,银行业危机仍可控?现货黄金暂守2360 近年来,美国房地产市场一直处于波动之中,尤其是商业房地产领域。近期,美联储发出警告,称商业房地产贷款逾期率持续攀升,银行正在为…...
SwiftUI中的@StateObject和@ObservedObject的区别
SwiftUI中的StateObject和ObservedObject属性包装器指示视图更新以响应被观察对象的变化。虽然这两个属性包装器看起来很相似,但在使用SwiftUI构建应用程序时,有一个关键的区别需要理解。 两个属性包装器都要求对象符合ObservableObject协议。这个协议表…...
类与对象(二)
封装 封装作为面向对象三大特性(封装,继承,多态)之一,那如何实现封装性的呢?就又得拿出上面的访问修饰限定符的图 public: 就是在任何地方都可以访问 protected: 涉及子类在介绍继承时详细介绍 default: …...
LeetCode/NowCoder-链表经典算法OJ练习2
最好的,不一定是最合适的;最合适的,才是真正最好的。💓💓💓 目录 说在前面 题目一:分割链表 题目二:环形链表的约瑟夫问题 SUMUP结尾 说在前面 dear朋友们大家好!&…...
英伟达解码性能NVDEC
如果你能打开官网,请看这里: NVDEC Application Note 下面是摘录:...
文心一言 VS 讯飞星火 VS chatgpt (255)-- 算法导论18.3 1题
一、请说明依次从图18-8(f)中删除C、P和V后的结果。如果要写代码,请用go语言。 文心一言: 首先,让我们明确一点:由于您没有提供具体的图18-8(f)的内容,我只能假设它是一个数据结构(可能是图、树或列表等&…...
C++ | Leetcode C++题解之第73题矩阵置零
题目: 题解: class Solution { public:void setZeroes(vector<vector<int>>& matrix) {int m matrix.size();int n matrix[0].size();int flag_col0 false;for (int i 0; i < m; i) {if (!matrix[i][0]) {flag_col0 true;}for …...
用 Supabase CLI 进行本地开发环境搭建
文章目录 (零)前言(一)Supabase CLI(1.1)安装 Scoop(1.2)用 Scoop 安装 Supabase CLI (二)本地项目环境(2.1)初始化项目(2…...
三极管 导通条件
一、三极管理解 三极管是电子行业常用的元器件之一,他是一种电流型控制的器件,他有三种工作状态:截止区,放大区、饱和区。当三极管当做开关使用时,他工作在饱和区。下面简短讲解三极管作为开关使用的方法,只…...
一次pytorch分布式训练精度调试过程
现象: loss不下降 过程如下: 1.减少层数,准备最小复现环境 2.dropout设置为0,重复运行二次,对比loss是否一致 3.第二次迭代开始loss不一致 4.对比backward之后的梯度,发现某一个梯度不一致 5.dump得到所有算子的规模,单算子测试…...
STM32(GPIO)
GPIO简介 GPIO(General Purpose Input Output)通用输入输出口 引脚电平:0V~3.3V,部分引脚可容忍5V 输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等 输入模式下可读取端口的高低电…...
python设计模式---观察者模式
观察者模式是一种行为设计模式,用于定义对象之间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都会得到通知并自动更新。 from abc import ABC, abstractmethod from typing import Listclass Observable:def __init__(sel…...
【论文笔记】KAN: Kolmogorov-Arnold Networks 全新神经网络架构KAN,MLP的潜在替代者
KAN: Kolmogorov-Arnold Networks code:https://github.com/KindXiaoming/pykan Background 多层感知机(MLP)是机器学习中拟合非线性函数的默认模型,在众多深度学习模型中被广泛的应用。但MLP存在很多明显的缺点:…...
【投稿资讯】区块链会议CCF C -- CoopIS 2024 截止7.10 附录用率
会议名称:CoopIS CCF等级:CCF C类学术会议 类别:人机交互与普适计算 录用率:2023年接收率21% (21 regular 10 work-in-progress papers/100) AREA 5: HUMAN-CENTRIC SECURITY AND PRIVACY IN INFORMATION SYSTEMS Access Con…...
React Native 之 开发环境搭建(一)
1. 安装Node.js: Node.js是React Native开发的基础,因此首先需要安装Node.js。强烈建议始终选择 Node 当前的 LTS (长期维护)版本,一般是偶数版本,不要选择偏实验性质的奇数版本。 如果你希望更方便地管理…...
DS高阶:B树系列
一、常见的搜索结构 1、顺序查找 时间复杂度:O(N) 2、二分查找 时间复杂度:O(logN) 要求:(1)有序 (2)支持下标的随机访问 3、二叉搜索树(BS树) 时间复杂…...
第五百零三回
文章目录 1. 概念介绍2. 使用方法2.1 普通路由2.2 命名路由 3. 示例代码4. 内容总结 我们在上一章回中介绍了"使用get显示Dialog"相关的内容,本章回中将介绍使用get进行路由管理.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
