Spring Boot 项目 myblog 整理
myblog 项目是一个典型的 Spring Boot 项目,主要包括用户注册、登录、文章管理(创建、查询、更新、删除)等功能。
1. 项目结构与依赖设置
项目初始化与依赖
- 使用 Spring Initializr 创建项目。
- 引入必要的依赖包:
- Spring Boot Web:用于开发 REST API。
- MyBatis 和 MySQL 驱动:用于数据库交互。
- Spring Validation:用于验证用户输入。
- Lombok:减少样板代码。
- Hibernate Validator:手动加入以支持输入验证。
2. 数据库设计与建表
数据库表设计
- my_users:用于存储用户信息,包含字段:
id、name、email、password、role_id等。 - my_roles:用于存储用户角色,包含字段:
id、name、description等。 - my_articles:用于存储文章信息,包含字段:
id、title、author、content、category_id、tags、is_deleted、created、modified等。
SQL 表的相关操作
- 插入用户和角色:使用插入语句添加初始用户和角色数据。
- 外键约束与错误:注意在添加用户时,由于外键关系,必须确保角色 ID 存在。
3. 用户模块
用户实体类 (MyUser)
- 使用 Lombok 注解
@Data、@NoArgsConstructor、@AllArgsConstructor简化代码。 - 添加必要的字段验证注解,例如
@NotBlank和@NotNull。
用户注册与登录
- 注册功能:实现用户注册功能,使用
UserService服务层来处理业务逻辑。 - 登录功能:实现登录,验证用户名和密码,并通过
TokenService生成 JWT Token。
用户控制器 (UserController)
- 注册接口:使用
@PostMapping("/register"),调用UserService来进行用户注册。 - 登录接口:使用
@PostMapping("/login"),调用UserService登录并生成 Token,最后将 Token 作为 JSON 响应返回。
4. 文章管理模块
文章实体类 (MyArticle)
MyArticle:使用Lombok注解简化代码。- 字段:包括
id、title、author、content、categoryId、tags、isDeleted、created、modified。 - 字段验证:对必要的字段加上验证注解,如
@NotBlank和@NotNull。
- 字段:包括
文章控制器 (ArticleController)
- 添加文章:
- 使用
@PostMapping("/article")添加新文章。 - 使用
@Validated注解对请求参数进行验证,若验证失败,通过BindingResult获取错误信息。
- 使用
- 查询文章:
- 获取所有文章:使用
@GetMapping("/articles"),不分页。 - 分页查询文章:使用
@GetMapping("/articles/{pageNum}"),通过传入的页码查询文章列表。
- 获取所有文章:使用
- 更新文章:
- 更新接口:使用
@PutMapping("/article")。 - 检查传入的文章对象是否包含 ID,并验证其字段。
- 调用
ArticleService更新文章。
- 更新接口:使用
- 删除文章:
- 软删除接口:使用
@DeleteMapping("/article/{id}")。 - 实现软删除,通过修改
isDeleted字段为2来实现逻辑删除。
- 软删除接口:使用
文章服务层 (ArticleService)
- 添加文章 (
add):为文章设置 ID 并存储。 - 查询所有文章 (
findAll):查询所有文章,未分页。 - 分页查询文章 (
getListByPageNum):根据传入的页码计算偏移量来查询分页文章。 - 文章详情 (
detail):根据文章 ID 查询文章详情。 - 更新文章 (
update):更新文章信息。 - 删除文章 (
delete):软删除文章,修改isDeleted字段。
文章 Mapper (MyArticleMapper)
- 使用 MyBatis 注解
@Mapper定义数据库操作。 - 新建文章:使用
@Insert注解插入文章。 - 查询文章:
- 不分页:使用
@Select("SELECT * FROM my_articles WHERE is_deleted = 1")查询所有未删除的文章。 - 分页:使用
@Select("SELECT * FROM my_articles WHERE is_deleted = 1 LIMIT #{offset}, 30")分页查询。 - 查询详情:通过文章
id查询文章详情。
- 不分页:使用
- 更新文章:使用
@Update更新文章内容。 - 软删除文章:使用
@Update("UPDATE my_articles SET is_deleted = 2 WHERE id = #{id}")实现软删除。
5. 错误处理与验证
输入验证
- 添加和更新文章:使用
@Validated注解验证输入数据,并使用BindingResult来捕获验证错误。 - Controller 层:对错误返回相应的错误码和消息,方便前端处理。
全局异常处理
- 异常处理机制:在每个控制器方法中使用
try-catch来捕获异常,返回JsonResultObject,将错误信息统一封装在响应中,确保系统健壮性。
6. Token 处理
- 登录时生成 Token:
- 在
UserController的/login方法中调用TokenService生成 Token,返回给客户端用于后续请求的认证。
- 在
- 权限验证:
- 使用自定义注解和拦截器来验证每个请求是否携带有效的 Token,用于保护需要认证的接口(例如,添加、更新、删除文章)。
7. 项目运行与测试
本地测试
- 数据库初始化:确保所有的数据库表已经正确创建,并且初始数据(如用户角色)已插入。
- Postman 测试接口:
- 用户注册与登录:通过
/v1/register和/v1/login测试用户注册和登录功能,登录成功后获取 Token。 - 文章接口:
- 添加文章:使用
/v1/article通过 POST 请求添加新文章。 - 查询文章:通过
/v1/articles或/v1/articles/{pageNum}测试文章列表的查询。 - 更新与删除文章:分别通过 PUT 和 DELETE 请求测试更新和删除文章。
- 添加文章:使用
- 用户注册与登录:通过
8. 关键问题与解决方案
- SQL 外键约束错误:在插入用户数据时确保角色数据已存在,避免外键约束失败。
- Token 未返回问题:确保登录逻辑中成功生成 Token,并将其正确返回给前端。
- 验证失败的处理:在控制器中使用
BindingResult检查参数错误,并及时返回有意义的错误信息。 - 重复方法定义错误:在
MyArticleMapper中避免重复的方法定义,保证每个方法的名称唯一且功能明确。
总结
- 项目基于 Spring Boot,结合了 MyBatis 和 Hibernate Validator 等技术栈,适用于构建一个基本的博客系统。
- 包含了用户管理和文章管理模块,并实现了增删改查功能。
- 使用 JWT Token 进行用户身份认证,保证了部分接口的安全性。
- 在开发过程中,通过单独的 Service 层来处理业务逻辑,将控制器层的职责简化为参数验证与返回结果的封装,确保代码的可维护性和扩展性。
相关文章:
Spring Boot 项目 myblog 整理
myblog 项目是一个典型的 Spring Boot 项目,主要包括用户注册、登录、文章管理(创建、查询、更新、删除)等功能。 1. 项目结构与依赖设置 项目初始化与依赖 使用 Spring Initializr 创建项目。引入必要的依赖包: Spring Boot W…...
uniapp 城市选择插件
uniapp城市选择插件 如上图 地址 完整demo <template><view><city-selectcityClick"cityClick":formatName"formatName":activeCity"activeCity":hotCity"hotCity":obtainCitys"obtainCitys":isSearch&quo…...
测试工程师如何在面试中脱颖而出
目录 1.平时工作中是怎么去测的? 2.B/S架构和C/S架构区别 3.B/S架构的系统从哪些点去测? 4.你为什么能够做测试这一行?(根据个人情况分析理解) 5.你认为测试的目的是什么? 6.软件测试的流程ÿ…...
Mesh路由组网
Mesh无线网格网络,多跳(multi-hop)网络,为解决全屋覆盖信号,一般用于家庭网络和小型企业 原理 网关路由器(主路由,连接光猫),Mesh路由器(子路由,…...
LeetCode131:分割回文串
题目链接:131. 分割回文串 - 力扣(LeetCode) 代码如下: class Solution { private:vector<vector<string>> result;vector<string> path; // 放已经回文的子串void backtracking (const string& s, int s…...
详细解析 devmem 命令:在 Linux 系统中直接访问内存的利器
目录 什么是 devmem?为什么需要 devmem?devmem 命令的基本语法devmem 在硬件调试中的应用安全性与风险devmem 的常见应用示例结论 在嵌入式系统开发和硬件调试中,开发者经常需要直接与硬件打交道,访问和修改内存中某些特定区域的内…...
[Docker-显示所有容器IP] 显示docker-compose.yml中所有容器IP的方法
本文由Markdown语法编辑器编辑完成。 1. 需求背景: 最近在启动一个服务时,突然发现它的一个接口,被另一个服务ip频繁的请求。 按理说,之前设置的是,每隔1分钟请求一次接口。但从日志来看,则是1秒钟请求一次ÿ…...
【前端知识】nodejs项目配置package.json深入解读
package.json详细解读 文件解读一、文件结构二、字段详解三、使用场景四、注意事项 组件版本匹配规则 文件解读 package.json 文件是 Node.js 项目中的一个核心配置文件,它位于项目的根目录下,并包含项目的基本信息、依赖关系、脚本、版本等内容。以下是…...
XGBOOST算法Python实现(保姆级)
摘要 XGBoost算法(eXtreme Gradient Boosting)在目前的Kaggle、数学建模和大数据应用等竞赛中非常流行。本文将会从XGBOOST算法原理、Python实现、敏感性分析和实际应用进行详细说明。 目录 0 绪论 一、材料准备 二、算法原理 三、算法Python实现 3…...
JDK、MAVEN与IDEA的安装与配置
1.认识JDK、MAVEN与IDEA JDK 提供了编译和运行Java程序的基本环境。Maven 帮助管理项目的构建和依赖。IDEA 提供了一个强大的开发环境,使得编写、调试和运行Java程序更加高效。 2. 安装与环境配置 2.1 官网地址 选择你需要的版本下载: MAVEN下载传送…...
输出比较简介
输出比较简介 主要是用来输出PWM波形,这个波形是驱动电机的(智能车和机器人等)必要条件 OC(Output Compare)输出比较,还有IC,全称是Input Capture,意为输入捕获,还有CC…...
什么是反向 DNS 查找以及它的作用是什么?
反向DNS查询(rDNS)是一种技术,用于确定与某个IP地址对应的域名。当我们对一个IP地址进行反向DNS查询时,实际上是向域名系统(DNS)的特殊部分请求信息,这部分被称为PTR记录。PTR记录会返回与这个I…...
集群聊天服务器(13)redis环境安装和发布订阅命令
目录 环境安装订阅redis发布-订阅的客户端编程环境配置客户端编程 功能测试 环境安装 sudo apt-get install redis-server 先启动redis服务 /etc/init.d/redis-server start默认在6379端口上 redis是存键值对的,还可以存链表、数组等等复杂数据结构 而且数据是在…...
[ubuntu]编译共享内存读取出现read.c:(.text+0x1a): undefined reference to `shm_open‘问题解决方案
问题log /tmp/ccByifPx.o: In function main: read.c:(.text0x1a): undefined reference to shm_open read.c:(.text0xd9): undefined reference to shm_unlink collect2: error: ld returned 1 exit status 程序代码 #include <stdio.h> #include <stdlib.h> #…...
Python Matplotlib 安装指南:使用 Miniconda 实现跨 Linux、macOS 和 Windows 平台安装
Python Matplotlib 安装指南:使用 Miniconda 实现跨 Linux、macOS 和 Windows 平台安装 Matplotlib是Python最常用的数据可视化工具之一,结合Miniconda可以轻松管理安装和依赖项。在这篇文章中,我们将详细介绍如何使用Miniconda在Linux、mac…...
DimensionX 部署笔记
目录 生成视频用CogVideoX-5b-I2V 推理代码: DimensionX 生成视频用CogVideoX-5b-I2V 推理代码: 可以生成,从左向右旋转的,也可以生成从上往下旋转的: import torch from diffusers import CogVideoXImageToVideo…...
django从入门到精通(五)——表单与模型
好的,下面将详细介绍 Django 的表单与模型,包括它们的定义、使用、如何在 Django Admin 中结合使用,以及相关的字段类型和验证机制。 Django 模型与表单 1. Django 模型 Django 模型是一个 Python 类,用于定义数据库中的数据结…...
C语言Day 03 学习总结
Day 03 学习总结 流程控制语句 顺序结构 程序从上到下依次执行。每一条语句顺序执行,直到结束。 选择结构 程序根据条件选择执行某一条分支。包括 if-else 和 switch-case。 循环结构 程序反复执行某段代码。包括 for、while、do-while。 跳转结构 控制程序直接跳…...
kafka中是如何快速定位到一个offset的
定位到具体的segment日志文件,采用二分法先定位到index索引文件计算查找的offset在日志文件的相对偏移量 1、分区和日志段: 每个主题的分区(Partition)被划分为多个日志段(Log Segment)。每个日志段是一个…...
视频对接rtsp协议学习
RTSP协议在视频平台中的应用 RTSP(Real Time Streaming Protocol)是一种基于TCP/IP的应用层协议,主要用于控制流媒体数据的传输和播放。它通过定义一系列命令和请求,实现对流媒体服务器的远程控制,但不传输媒体数据…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
