【博客系统】博客系统第一弹:博客系统项目配置、MyBatis-Plus 实现 Mapper 接口、处理项目公共模块:统一返回结果、统一异常处理
案例综合练习 - 博客系统
本节目标
- 从 0 到 1 完成博客系统后端项目的开发。
前言
通过前面课程的学习,我们掌握了 Spring 框架和 MyBatis 的基本使用,并完成了图书管理系统的常规功能开发。接下来我们系统地从 0 到 1 完成一个项目的开发。
项目介绍
使用 SSM 框架实现一个简单的博客系统,共 5 个页面:
- 用户登录
- 博客发表页
- 博客编辑页
- 博客列表页
- 博客详情页
功能描述:用户登录成功后,可以查看所有人的博客。点击“查看全文”可以查看该博客的正文内容。如果该博客作者为当前登录用户,可以完成博客的修改和删除操作,以及发表新博客。(前端页面随课堂资料一起提供)
页面预览
- 用户登录
- 博客列表页
- 博客详情页
- 博客发表/修改页
数据准备
建表 SQL:
-- 建表 SQL
create database if not exists java_blog_spring charset utf8mb4;use java_blog_spring;-- 用户表
DROP TABLE IF EXISTS java_blog_spring.user_info;
CREATE TABLE java_blog_spring.user_info(
`id` INT NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR (128) NOT NULL,
`password` VARCHAR (128) NOT NULL,
`github_url` VARCHAR (128) NULL,
`delete_flag` TINYINT (4) NULL DEFAULT 0,
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY (id),
UNIQUE INDEX user_name_UNIQUE (user_name ASC)) ENGINE = INNODB DEFAULT CHARACTER SET = utf8mb4 COMMENT = '用户表';-- 博客表
drop table if exists java_blog_spring.blog_info;
CREATE TABLE java_blog_spring.blog_info (
`id` INT NOT NULL AUTO_INCREMENT,
`title` VARCHAR(200) NULL,
`content` TEXT NULL,
`user_id` INT(11) NULL,
`delete_flag` TINYINT(4) NULL DEFAULT 0,
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY (id))
ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '博客表';-- 新增用户信息
insert into java_blog_spring.user_info (user_name, password, github_url) values("zhangsan", "123456", "https://gitee.com/bubblefish666/class-java45");
insert into java_blog_spring.user_info (user_name, password, github_url) values("lisi", "123456", "https://gitee.com/bubblefish666/class-java45");insert into java_blog_spring.blog_info (title, content, user_id) values("第一篇博客", "111我是博客正文我是博客正文我是博客正文", 1);
insert into java_blog_spring.blog_info (title, content, user_id) values("第二篇博客", "222我是博客正文我是博客正文我是博客正文", 2);
创建项目
创建 SpringBoot 项目,添加 Spring MVC 和 MyBatis 对应依赖。
添加MyBatis-Plus 依赖
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version>
</dependency>
删除引入 lombok 依赖添加的多余插件:
创建对应目录
准备前端页面
把课程中提供的博客系统静态页面拷贝到 static
目录下。
配置配置文件
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/java_blog_spring?characterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Drivermybatis-plus:configuration:map-underscore-to-camel-case: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImpllogging:file:name: spring-blog.log
测试
访问前端页面:http://127.0.0.1:8080/blog_login.html。前端页面可以正确显示,说明项目初始化成功。
项目公共模块
项目分为控制层(Controller)、服务层(Service)、持久层(Mapper)。各层之间的调用关系如下:
我们先根据需求完成公共层代码的编写。
统一返回结果实体类
- code:业务状态码
- 200:业务处理成功
- -1:业务处理失败
- 后续有其他异常信息,可以再补充。
- errMsg:业务处理失败时,返回的错误信息。
- data:业务返回数据。
定义业务状态枚举:
基于会话管理 Session 、统一响应封装、枚举状态码、工厂方法模式实现状态码方法:全栈开发获取图书列表接口的强制登录功能(含会话管理、统一响应封装思维导图、核心部分代码)
后面需要把 Object data 修改为泛型:
@Data
public class Result<T> {private int code;private String errMsg;private T data;public static <T> Result success(T data) {Result result = new Result();result.setCode(ResultCodeEnum.SUCCESS.getCode());result.setData(data);return result;}public static <T> Result fail(String errMsg) {Result result = new Result();result.setCode(ResultCodeEnum.FAIL.getCode());result.setErrMsg(errMsg);return result;}
}
统一返回结果
统一返回结果封装:封装 String 类型造成参数类型不匹配异常、通过 Debug 锁定调用链出现异常的具体位置、解决异常的方法_springboot 报错返回类封装
定义项目异常
import com.bite.blog.common.pojo.response.Result;public class BlogException extends RuntimeException {private Result errorResult = new Result<>();public BlogException(String message) {this.errorResult.setCode(-1);this.errorResult.setErrMsg(message);}
}
统一异常处理
@ControllerAdvice(含底层源码分析) 、@ExceptionHandler、@ResponseBody 配合实现统一异常处理功能
@RestController 变成 @Controller ,方法的返回值会被当成 URL,使用 @ResponseBody 会告诉 Spring 返回结果是数据而非页面
import com.bite.blog.common.pojo.response.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;@Slf4j
@RestControllerAdvice
public class ExceptionAdvice {@ExceptionHandlerpublic Result handler(Exception e) {log.error("发生异常, e: {}", e);return Result.fail(e.getMessage());}
}
业务代码
实体类
在数据库中,我们创建了两张表,接下来需要创建两个类,来与之对应;
对应机制:yml 驼峰自动转换/MP 依赖 ???
UserInfo
@Data
public class UserInfo {@TableId(type = IdType.AUTO)private Integer id;private String userName;private String password;private String githubUrl;private Integer deleteFlag;private LocalDate createTime;private LocalDate updateTime;
}
因为数据库的表名,列名都能和 MyBatis-Plus 中设置的实体类,属性对上,就不需要使用 @TableName
,@TableField
来指定表和类、字段和属性;
但是需要使用 @TableId(type = IdType.AUTO)
设置主键,并且设置该主键类型为自增主键;
@TableName、@TableField、@TableId 的使用方法在这篇博客中有提及
BlogInfo
@Data
public class BlogInfo {@TableId(value = "id", type = IdType.AUTO)private Integer id;private String title;private String content;private Integer userId;private Integer deleteFlag;private LocalDateTime createTime;private LocalDateTime updateTime;
}
持久层
使用 MyBatisPlus 来完成持久层代码的开发,创建 mapper 实现 BaseMapper
即可。
Mapper
MP:依赖引入、继承 BaseMapper 接口实现单表增删改查、MP日志配置、表设计中设置主键自增值、MP 相关的 @Table系列常见注解说明_
@Mapper 用于标识该接口是 MyBatis 中的 Mapper接口
相关文章:

【博客系统】博客系统第一弹:博客系统项目配置、MyBatis-Plus 实现 Mapper 接口、处理项目公共模块:统一返回结果、统一异常处理
案例综合练习 - 博客系统 本节目标 从 0 到 1 完成博客系统后端项目的开发。 前言 通过前面课程的学习,我们掌握了 Spring 框架和 MyBatis 的基本使用,并完成了图书管理系统的常规功能开发。接下来我们系统地从 0 到 1 完成一个项目的开发。 项目介绍 …...
如何通过挖掘需求、SEO优化及流量变现成功出海?探索互联网产品的盈利之道
挖掘需求,优化流量,实现变现:互联网出海产品的成功之路 在当今全球化的数字时代,越来越多的企业和个人选择将业务扩展到国际市场。这一趋势不仅为企业带来了新的增长机会,也为个人提供了通过互联网产品实现盈利的途径…...
车载功能测试-车载域控/BCM控制器测试用例开发流程【用例导出方法+优先级划分原则】
目录 1 摘要2 位置灯手动控制简述2.1 位置灯手动控制需求简述2.2 位置灯手动控制逻辑交互图 3 用例导出方法以及优先级原则3.1 用例导出方法3.1.1 用例导出方法介绍3.1.2 用例导出方法关键差异分析 3.2 优先级规则3.2.1 优先级划分的核心原则3.2.2 具体等级定义与判定标准 3.3 …...

基于OpenMV+STM32+OLED与YOLOv11+PaddleOCR的嵌入式车牌识别系统开发笔记
基于OpenMV、STM32与OLED的嵌入式车牌识别系统开发笔记 基于OpenMV、STM32与OLED的嵌入式车牌识别系统开发笔记系统架构全景 一、实物演示二、OpenMV端设计要点1. 硬件配置优化2. 智能帧率控制算法3. 数据传输协议设计 三、PyTorch后端核心实现:YOLOv11与PaddleOCR的…...
MCP实战-本地MCP Server + Client实战
概述 本文开发一个MCP的Client和Server。然后通过本地模式来运行,并获取到server的结果。 MCP Server开发 import anyio import click import mcp.types as types from mcp.server.lowlevel import Server from pydantic import FileUrlSAMPLE_RESOURCES {"…...

w~嵌入式C语言~合集4
我自己的原文哦~ https://blog.51cto.com/whaosoft/13870376 一、STM32怎么选型 什么是 STM32 STM32,从字面上来理解,ST是意法半导体,M是Microelectronics的缩写,32表示32位,合起来理解,STM32就是指S…...
lightrag : from lightrag.utils import EmbeddingFunc 报错
原因: 1. 同时安装了lightrag与lightrag-hku 解决方法: 卸载原有的lightrag与lightrag-hku,只安装lightrag-hku pip install lightrag-hku...
ppt流程图怎么?ppt流程图模板大全
ppt流程图怎么?ppt流程图剪头模板,ppt流程图模板大全: ppt流程图_模板素材_PPT模板_ppt素材_免抠图片_AiPPTer...
AWS中国区ICP备案全攻略:流程、注意事项与最佳实践
导语 在中国大陆地区开展互联网业务时,所有通过域名提供服务的网站和应用必须完成ICP备案(互联网内容提供商备案)。对于选择使用AWS中国区(北京/宁夏区域)资源的用户,备案流程因云服务商的特殊运营模式而有所不同。本文将详细解析AWS中国区备案的核心规则、操作步骤及避坑…...

腾讯云服务器安全——服务防火墙端口放行
点击服务进入安全策略 添加规则...
对局匹配--stl+模拟
1.模拟,先找匹配对数,然后减 2.特殊情况,k0 3.stl容器使用,lower_bound https://www.luogu.com.cn/problem/P8656 #include<bits/stdc.h> using namespace std; #define N 100011 typedef long long ll; typedef pair&…...

K8S安全认证
一。用户认证的基本框架 在K8S集群中,客户端通常有两类: 1.User Account:一般独立于K8S之外的其他服务管理的用过户账号 2.Service Account:K8S管理的账号,用于为Pod中的服务进程在访问K8S提供身份标识 ApiServer是…...

mybatis-plus里的com.baomidou.mybatisplus.core.override.MybatisMapperProxy 类的详细解析
以下是 com.baomidou.mybatisplus.core.override.MybatisMapperProxy 类的详细解析: 1. 类的作用 MybatisMapperProxy 是 MyBatis-Plus 框架中用于实现 Mapper 接口动态代理的核心类。它继承自 MyBatis 的 MapperProxy,并扩展了以下功能: …...

在java程序中,类,进程,线程他们之间的关系以及main方法与他们之间的关系
在 Java 程序里,类、进程、线程各自有着不同的概念,同时也存在着紧密的联系,下面来详细分析它们之间的关系以及 main 方法和它们的关系。 类 类是 Java 中最基础的编程单元,是一种自定义的数据类型,它定义了对象的属…...

[ACTF2020 新生赛]BackupFile题解
启动环境 进入后只有一段话,没有其他的说法。 解题方法 但是题目命名为backup file,应该是备份文件的意思,那么就用dirsearch工具来扫一下看看。 查看扫描结果 index.php.bak 下载下这个文件,查看文件内容。 进行php代码审计…...

如何修改npm的全局安装路径?
修改 npm 的全局安装路径可以通过以下步骤完成,确保全局包(使用 -g 安装的模块)和缓存文件存储到自定义路径。以下是详细步骤: 1. 创建自定义路径的目录 在目标路径下创建两个文件夹,分别用于存储全局模块和缓存文件…...

巧用 Element - UI 实现图片上传按钮的智能隐藏
引言 在前端开发中,使用 Element - UI 组件库来构建用户界面是非常常见的操作。其中图片上传功能更是在许多项目中频繁出现,比如用户头像上传、商品图片上传等场景。有时候,我们会有这样的需求:当上传图片达到一定数量后…...
Ubuntu18.04 升级最新版本Cmake
1.升级原因 ubuntu18.04默认安装的cmake版本为 3.10.2;在编译一些软件的时候,版本太低导致无法编译 2.从cmake官网下载二进制安装包 地址:https://cmake.org/download/ 包:cmake-4.0.1-linux-x86_64.tar.gz 3.上传下载好的安装包到ubuntu…...
关于mysql的事务和索引
1. 事务四大特性(ACID) 原子性:事务的操作要么全部成功,要么全部失败回滚,不可分割。 一致性:事务执行前后,数据必须满足业务规则(如账户总额不变)。 隔离性࿱…...

从“拼凑”到“构建”:大语言模型系统设计指南!
你有没有试过在没有说明书的情况下组装宜家家具?那种手忙脚乱却又充满期待的感觉,和设计大语言模型(LLM)系统时如出一辙。如果没有一个清晰的计划,很容易陷入混乱。我曾经也一头扎进去,满心期待却又手足无措,被网上那些复杂的架构图搞得晕头转向。于是,我坐下来,把它们…...
mybatis xml中特殊字符处理
1,CDATA区: 它的全称为character data,以"<![CDATA[ "开始,以" ]]>" 结束,在两者之间嵌入不想被解析程序解析的原始数据,解析器不对CDATA区中的内容进行解析,而是将这些数据原封…...

【数据结构与算法】从完全二叉树到堆再到优先队列
完全二叉树 CBT 设二叉树的深度为 h , 若非最底层的其他各层的节点数都达到最大个数 , 最底层 h 的所有节点都连续集中在左侧的二叉树叫做 完全二叉树 . 特点 对任意节点 , 其右分支下的叶子节点的最底层为 L , 则其左分支下的叶子节点的最低层一定是 L 或 L 1 .完全二叉树…...
【linux】SSH 连接 WSL2 本地环境的完整步骤
SSH 连接 WSL2 本地环境的完整步骤 要在 Windows 的 WSL2 环境中启用 SSH 服务,并允许本地或局域网设备连接,需完成以下步骤: 1. 安装 openssh-server sudo apt update sudo apt install openssh-server -y2. 配置 sshd 修改配置文件 sud…...
vue项目前后端分离设计
在Vue前端架构中,通过分层结构和模块化设计实现高效的前后端分离,需要系统性规划各层职责、接口管理和数据流控制。以下是结合业界最佳实践的完整方案: 一、分层架构设计 1. 分层结构(自上而下) 层级职责示例技术实现…...

【Linux网络】构建类似XShell功能的TCP服务器
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...

Spring Boot 配置源详解(完整版)
Spring Boot 配置源详解(完整版) 一、配置源加载顺序与优先级 配置源类型优先级顺序(从高到低)对应配置类/接口是否可覆盖典型文件/来源命令行参数(--keyvalue)1(最高)SimpleComman…...
JDK 17 与 Spring Cloud Gateway 新特性实践指南
一、环境要求与版本选择 1. JDK 17 的必要性 最低版本要求:Spring Boot 3.x 及更高版本(如 3.4)强制要求 JDK 17,以支持 Java 新特性(如密封类、模式匹配)和性能优化。JDK 17 核心特性: 密封类…...
异构迁移学习(无创脑机接口中的跨脑电帽迁移学习)
本文介绍BCI中的跨脑电帽的迁移学习最新算法。 (发表于2025 arxiv,应该属于投稿阶段,这个场景具有非常不错的研究意义和前景) 最新跨脑电帽异构算法github开源代码 SDDA算法原文 一、脑机接口绪论 脑机接口(BCI)指在人或动物大脑与外部设备之间创建的直接连接,通过脑…...

puppeteer注入浏览器指纹过CDP
一、背景 通过puppeteer爬取目标网站时,经常会被对方网站检测到,比如原生puppeteerCDP特征非常明显,另外指纹如果一直不变,也会引发风控 二、实现 通过以下几行代码即可轻松过大部分检测点,并且能够切换指纹&#x…...
1.8软考系统架构设计师:系统架构设计师概述 - 练习题附答案及超详细解析
系统架构设计师概述综合知识单选题 每道题均附有答案解析: 架构设计师的定义、职责和任务 1、系统架构设计师的核心职责是: A. 编写具体功能模块的代码 B. 制定系统整体架构和技术选型 C. 管理项目预算和进度 D. 直接对接客户进行销售支持 答案&#x…...