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…...
【前端知识】nodejs项目配置package.json深入解读
package.json详细解读 文件解读一、文件结构二、字段详解三、使用场景四、注意事项 组件版本匹配规则 文件解读 package.json 文件是 Node.js 项目中的一个核心配置文件,它位于项目的根目录下,并包含项目的基本信息、依赖关系、脚本、版本等内容。以下是…...
51c嵌入式~IO合集2
我自己的原文哦~ https://blog.51cto.com/whaosoft/11697814 一、STM32串口通信基本原理 通信接口背景知识 设备之间通信的方式 一般情况下,设备之间的通信方式可以分成并行通信和串行通信两种。并行与串行通信的区别如下表所示。 串行通信的分类 1、按照数据传…...
在应用启动时,使用 UniApp 提供的 API 检查和请求权限。
在使用 UniApp 开发 App 时,如果你需要在应用启动时提示用户获取本地媒体权限,可以按照以下步骤操作: 1. 明确需要的权限 要访问本地媒体(如相机、麦克风或文件存储),需要申请以下权限: Andr…...
前端知识点---伪数组是什么 , 伪数组如何转换为真数组(Javascript)
伪数组是什么 , 伪数组如何转换为真数组(Javascript) 在 JavaScript 中,伪数组对象是具有类似数组特性的对象,但并不是数组(即不继承 Array.prototype)。这些对象通常有一个 length 属性以及以数字索引为键的属性,但不…...
嵌入式 UI 开发的开源项目推荐
嵌入式开发 UI 难吗?你的痛点我懂!作为嵌入式开发者,你是否也有以下困扰?设备资源太少,功能和美观只能二选一?调试效率低,每次调整都要反复烧录和测试?开发周期太长,让你…...
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
在 C编程的世界里,智能指针无疑是管理内存资源的得力助手。它们为我们自动处理内存的分配与释放,极大地减少了因手动管理内存而可能引发的诸如内存泄漏、悬空指针等棘手问题。然而,就像任何工具都有其两面性一样,智能指针在带来便…...
28.<Spring博客系统⑤(部署的整个过程(CentOS))>
引入依赖 Spring-boot-maven-plugin 用maven进行打包的时候必须用到这个插件。看看自己pom.xml中有没有这个插件 并且看看配置正确不正常。 注:我们这个项目打的jar包在30MB左右。 <plugin><groupId>org.springframework.boot</groupId><artif…...
mongodb多表查询,五个表查询
需求是这样的,而数据是从mysql导入进来的,由于mysql不支持数组类型的数据,所以有很多关联表。药剂里找药物,需要药剂与药物的关联表,然后再找药物表。从药物表里再找药物与成分关联表,最后再找成分表。 这里…...
服务器端渲染 (SSR) 与客户端渲染 (CSR)
嘿程序员!我们都知道,新时代的 Javascript 已经彻底改变了现代网站的结构和用户体验。如今,网站的构建更像是一个应用程序,伪装成一个能够发送电子邮件、通知、聊天、购物、支付等的网站。今天的网站是如此先进、互动,…...
【已解决】“EndNote could not connect to the online sync service”问题的解决
本人不止一次在使用EndNote软件时遇到过“EndNote could not connect to the online sync service”这个问题。 过去遇到这个问题都是用这个方法来解决: 这个方法虽然能解决,但工程量太大,每次做完得歇半天身体才能缓过来。 后来再遇到该问…...
HTML5拖拽API学习 托拽排序和可托拽课程表
文章目录 前言拖拽API核心概念拖拽式使用流程例子注意事项综合例子🌰 可拖拽课程表拖拽排序 前言 前端拖拽功能让网页元素可以通过鼠标或触摸操作移动。HTML5 提供了标准的拖拽API,简化了拖放操作的实现。以下是拖拽API的基本使用指南: 拖拽…...
sed使用扩展正则表达式时, -i 要写在 -r 或 -E 的后面
sed使用扩展正则表达式时, -i 要写在 -r 或 -E 的后面 前言 -r 等效 -E , 启用扩展正则表达式 -E是新叫法,更统一,能增强可移植性 , 但老系统,比如 CentOS-7 的 sed 只能用 -r ### Ubuntu24.04-E, -r, --regexp-extendeduse extended regular expressions in the script(fo…...
CSS中Flex布局应用实践总结
① 两端对齐 比如 要求ul下的li每行四个,中间间隔但是需要两段对齐,如下图所示: 这是除了基本的flex布局外,还需要用到:nth-of-type伪类来控制每行第一个与第四个的padding。 .hl_list{width: 100%;display: flex;align-items…...
【前端】CSS修改div滚动条样式
示例 分别是滚动条默认样式和修改后的样式 代码 <div class"video-list"><div class"list-item" onclick"videoinfo(100)"><img src"/index/images/coverimg/方和谦.png"><div class"txt">国医大…...
鸿蒙多线程开发——线程间数据通信对象02
1、前 言 本文的讨论是接续鸿蒙多线程开发——线程间数据通信对象01的讨论。在上一篇文章中,我们讨论了常规的JS对象(普通JSON对象、Object、Map、Array等)、ArrayBuffer。其中讨论了ArrayBuffer的复制传输和转移传输方式。 下面,我们将讨论SharedArra…...
Kotlin的data class
在 Kotlin 中,data class 是一种专门用来存储数据的类。与普通类相比,data class 提供了简化数据存储的语法,并且自动生成了一些常用的方法,例如 toString()、equals()、hashCode() 和 copy()。 1. 定义 data class data class …...
Proxy 在 JavaScript的用法
Proxy 是 JavaScript 提供的一个构造函数,用于创建一个“代理对象”。这个代理对象可以拦截目标对象的基本操作,例如读取属性、赋值、删除、调用函数等。通过它,我们可以修改或扩展对象的默认行为。 Proxy 的基本语法 const proxy = new Proxy(target, handler);target:被…...
vue3的attr透传属性详解和使用法方式。以及在css样式的伪元素中实现
在 Vue 3 和 TypeScript 中,属性透传(attr pass-through)是指将组件的属性传递到其根元素或某个子元素中。这个概念在开发可复用的组件时非常有用,尤其是当你希望将父组件的属性动态地传递给子组件的某个 DOM 元素时。 在 Vue 3 …...
《人工智能深度学习的基本路线图》
《人工智能深度学习的基本路线图》 基础准备阶段 数学基础: 线性代数:深度学习中大量涉及矩阵运算、向量空间等概念,线性代数是理解和处理这些的基础。例如,神经网络中的权重矩阵、输入向量的运算等都依赖于线性代数知识。学习内容…...
Matlab 答题卡方案
在现代教育事业的飞速发展中,考试已经成为现代教育事业中最公平的方式方法,而且也是衡量教与学的唯一方法。通过考试成绩的好与坏,老师和家长可以分析出学生掌握的知识多少和学习情况。从而老师可以了解到自己教学中的不足来改进教学的方式方…...
[Unity]TileMap开发,TileMap地图缝隙问题
环境: windows11 unity 2021.3.14f1c1 tilemap使用的图是美术已经拼接到一起的整图,块与块之间没有留缝隙 问题: TileMap地图直接在Unity中使用时,格子边缘会出现缝隙,移动或缩放地图时较明显。 解决方案&#x…...
pnpm : 无法加载文件 D:\Tool\environment\NodeAndNvm\node\pnpm.ps1,因为在此系统上禁止运行脚本。
问题 在终端(cmd)输入 pnpm -v,报错如下 pnpm : 无法加载文件 D:\Tool\environment\NodeAndNvm\node\pnpm.ps1,因为在此系统上禁止运行脚本。解决 1. 在终端输入get-ExecutionPolicy(查看执行策略/权限) 输出如下: # (受限的) Restricte…...
redis的map底层数据结构 分别什么时候使用哈希表(Hash Table)和压缩列表(ZipList)
在Redis中,Hash数据类型的底层数据结构可以是压缩列表(ZipList)或者哈希表(HashTable)。这两种结构的使用取决于特定的条件: 1. **使用ZipList的条件**: - 当Hash中的数据项(即f…...
通达OA前台submenu.php存在SQL注入漏洞(CVE-2024-10600)
通达OA前台submenu.php存在SQL注入漏洞(CVE-2024-10600) pda/appcenter/submenu.php 未包含inc/auth.inc.php且 $appid 参数未用’包裹导致前台SQL注入 影响范围 v2017-v11.6 fofa app"TDXK-通达OA" && icon_hash"-759108386"poc http://url…...
Flutter:photo_view图片预览功能
导入SDK photo_view: ^0.15.0单张图片预览,支持放大缩小 import package:flutter/material.dart; import package:photo_view/photo_view.dart;... ...class _MyHomePageState extends State<MyHomePage>{overrideWidget build(BuildContext context) {return…...
C++结构型设计模式之使用抽象工厂来创建和配置桥接模式的例子
下面是一个使用抽象工厂模式来创建和配置桥接模式的示例,场景是创建不同操作系统的窗口(Window)及其对应的实现(WindowImpl)。我们将通过抽象工厂来创建不同操作系统下的窗口和实现。 代码示例 #include <iostrea…...
智能合约运行原理
点个关注吧!! 用一句话来总结,智能合约就像是一个自动售货机:你投入硬币(触发条件),选择商品(执行合约),然后机器就会自动给你商品(执行结果&…...
Unity3D基于ECS的游戏逻辑线程详解
前言 Unity3D是一款非常流行的游戏开发引擎,其采用的是组件实体系统(ECS)架构,这种架构可以让游戏开发者更加高效地管理游戏逻辑线程。本文将详细介绍Unity3D基于ECS的游戏逻辑线程,并给出技术详解以及代码实现。 对…...
GIT 操作
全局设置 git config --global user.name "用户名" git config --global user.email "用户邮箱" 创建仓库 mkdir 项目目录 cd 项目目录 git init touch README.md git add README.md git commit -m "first commit" git remote add origin GIT…...
佛山三水戴尔R740服务器黄灯故障处理
1:佛山三水某某大型商场用户反馈一台DELL PowerEdge R740服务器近期出现了黄灯警告故障,需要冠峰工程师协助检查故障灯原因。 2:工程师协助该用户通过笔记本网线直连到服务器尾部的IDRAC管理端口,默认ip 192.168.0.120 密码一般在…...
系统性能优化方法论详解:从理解系统到验证迭代
在当今的企业级和云计算环境中,系统性能优化已成为提升竞争力的关键因素。本文将对系统优化的步骤进行深入解析,帮助读者系统化地进行性能优化,从而显著提升系统的整体表现。 流程概述: 系统性能优化的流程可以分为以下几个关键步骤&#x…...
241120学习日志——[CSDIY] [InternStudio] 大模型训练营 [09]
CSDIY:这是一个非科班学生的努力之路,从今天开始这个系列会长期更新,(最好做到日更),我会慢慢把自己目前对CS的努力逐一上传,帮助那些和我一样有着梦想的玩家取得胜利!!&…...
MySQL创建和管理触发器
1.在教务管理系统数据库d_eams的course表中,创建一个插入事件触发器tr_course,添加一条课程信息时,显示提示信息。 delimiter %% create trigger tr_course after insert on course for each row begin set tr_i 操作成功!; end…...
uniapp rpx兼容平板
问题: 使用uniapp开发平板端时, rpx/upx 内容过小, 没有适应屏幕 原因: uniapp 默认支持最大设备宽度为960px 而平板宽度超出了960 uniapp官方文档https://uniapp.dcloud.io/collocation/pages?idglobalstyle 解决: // pages.json 文件: {//..."globalSt…...
mysql 唯一键
在数据库中,唯一键(Unique Key)是一种约束条件,用于确保表中的某一列或多列组合的数据具有唯一性。这意味着在这列或这些列中不能有两个相同的值。唯一键的主要目的是保证数据的完整性和准确性,防止重复记录的插入。 …...
C++设计模式行为模式———迭代器模式
文章目录 一、引言二、迭代器模式三、总结 一、引言 迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。C标准库中内置了很多容器并提供了合适的迭代器,尽管我们不…...
Flutter:SlideTransition位移动画,Interval动画延迟
配置vsync,需要实现一下with SingleTickerProviderStateMixinclass _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{// 定义 AnimationControllerlate AnimationController _controller;overridevoid initState() {super.…...
Ruby Socket 编程
Ruby Socket 编程 Ruby 是一种动态、开放源代码的编程语言,以其简洁明了的语法和强大的功能而受到许多开发者的喜爱。在 Ruby 中,Socket 编程是一种重要的网络编程技术,它允许程序员创建可以在网络中通信的程序。本文将详细介绍 Ruby Socket 编程的基础知识,包括如何创建 …...
内容安全与系统构建加速,助力解决生成式AI时代的双重挑战
内容安全与系统构建加速,助力解决生成式AI时代的双重挑战 0. 前言1. PRCV 20241.1 大会简介1.2 生成式 Al 时代的内容安全与系统构建加速 2. 生成式 AI2.1 生成模型2.2 生成模型与判别模型的区别2.3 生成模型的发展 3. GAI 内容安全3.1 GAI 时代内容安全挑战3.2 图像…...
基于Vue的微前端架构实现与挑战
引言 微前端架构作为一种新兴的前端开发方案,能够有效解决大型应用的复杂性问题。本文将详细探讨基于Vue实现微前端的具体方案及其面临的挑战。 什么是微前端? 微前端是一种将前端应用分解成一系列更小、更易管理的独立应用的架构模式。每个子应用可以…...
UE5 DownloadImage加载jpg失败的解决方法
DownloadImage加载jpg失败的解决方法 现象解决方案具体方法 现象 用UE自带的 DownloadImage 无法下载成功,从 failure 引脚出来。 接入一个由监控器自动保存起的图像,有些可以正常加载成功,有些无法加载成功。 经调查问题出现在,…...
Consumer Group
不,kafka-consumer-groups.sh 脚本本身并不用于创建 Consumer Group。它主要用于管理和查看 Consumer Group 的状态和详情,比如列出所有的 Consumer Group、查看特定 Consumer Group 的详情、删除 Consumer Group 等。 Consumer Group 是由 Kafka 消费者…...
[开源] SafeLine 好用的Web 应用防火墙(WAF)
SafeLine,中文名 “雷池”,是一款简单好用, 效果突出的 Web 应用防火墙(WAF),可以保护 Web 服务不受黑客攻击 一、简介 雷池通过过滤和监控 Web 应用与互联网之间的 HTTP 流量来保护 Web 服务。可以保护 Web 服务免受 SQL 注入、XSS、 代码注…...
vue3 路由守卫
在Vue 3中,路由守卫是一种控制和管理路由跳转的机制。它允许你在执行导航前后进行一些逻辑处理,比如权限验证、数据预取等,从而增强应用的安全性和效率。路由守卫分为几种不同的类型,每种类型的守卫都有其特定的应用场景。 其实路…...
unigui 登陆界面
新建项目,因为我的Main页面做了其他的东西,所以我在这里新建一个form File -> New -> From(Unigui) -> 登录窗体 添加组件:FDConnection,FDQuery,DataSource,Unipanel和几个uniedit,…...
Ubuntu,openEuler,MySql安装
文章目录 Ubuntu什么是Ubuntu概述Ubuntu版本简介桌面版服务器版 部署系统新建虚拟机安装系统部署后的设置设置root密码关闭防火墙启用允许root进行ssh安装所需软件制作快照 网络配置Netplan概述配置详解配置文件DHCP静态IP设置 软件安装方法apt安装软件作用常用命令配置apt源 d…...
LLM( Large Language Models)典型应用介绍 1 -ChatGPT Large language models
ChatGPT 是基于大型语言模型(LLM)的人工智能应用。 GPT 全称是Generative Pre-trained Transformer。-- 生成式预训练变换模型: Generative(生成式):可以根据输入生成新的文本内容,例如回答问题…...
deepin系统下载pnpm cnpm等报错
deepin系统下载pnpm cnpm等报错 npm ERR! request to https://registry.npm.taobao.org/pnpm failed, reason: certificate has expired 报错提示证书过期,执行以下命令 npm config set registry https://registry.npmmirror.com下载pnpm npm install pnpm -g查…...
RPC-健康检测机制
什么是健康检测? 在真实环境中服务提供方是以一个集群的方式提供服务,这对于服务调用方来说,就是一个接口会有多个服务提供方同时提供服务,调用方在每次发起请求的时候都可以拿到一个可用的连接。 健康检测,能帮助从连…...