
做 Java 这些年带过新人也帮人改过不少课程设计和毕业设计我发现一个很普遍的现象很多人能照着教程写几个 CRUD 接口但一让他独立搭一个完整项目就卡壳——表怎么设计、目录怎么分、配置怎么写、部署到服务器上要注意什么全是坑。个人博客系统恰恰是解决这个问题的绝佳载体。今天要聊的这套基于 Java Spring Boot 的个人博客系统把源码、配套文档、运行视频、讲解视频四样东西都配齐了目的很直接让一个刚学完 Java 基础和 Spring Boot 的人能照着这套东西把一个完整项目跑起来、吃透它的设计思路最后改成自己的作品。这套系统不复杂但“麻雀虽小五脏俱全”。文章发布、分类归档、标签聚合、评论互动、后台管理一个典型博客该有的模块全都有。如果你正在纠结毕业设计选题或者想找个能完整落地、又不至于劝退的 Spring Boot 练手项目这篇内容基本能当操作手册用。我会从技术选型、功能模块、运行部署、常见坑点、二开建议这几个维度展开把我实际搞这套项目时的思路和经验都写出来。1. 项目定位与整体设计思路1.1 这套博客系统包了哪些东西先理清楚项目交付物是什么。除了源码本身这套项目的价值在于配套资料齐全一份文档负责讲明白数据库初始化和配置项修改一个运行视频演示从导入 IDEA 到启动成功的全过程还有一个讲解视频专门拆代码结构和核心逻辑。对于刚开始接触完整项目的人来说这种“文档 视频 源码”三合一的组合能有效避免“代码拿到了但不知道怎么跑”的尴尬。功能层面前台是访客视角的博客展示首页文章列表、文章详情、分类页面、标签页面、关于我、时间归档后台是管理员的创作管理登录认证、文章新增与编辑、分类和标签维护、评论管理。这样的功能划分和大多数个人博客系统保持了一致既不会因为模块太少而失去练习价值也不会因为过度设计而让新手看不懂。1.2 技术栈选型为什么以 Spring Boot 为核心个人博客这种项目技术选型的第一原则是“够用且能学到东西”。传统 SSMSpring Spring MVC MyBatis当然也能做但 XML 配置能写到你怀疑人生。Spring Boot 最大的贡献是自动化配置和起步依赖Starter把过去一大堆繁琐的配置收敛到几个注解和一份简洁的application.yml里内置的 Tomcat 又让你不用单独部署 War 包一个java -jar就能跑起来。本项目采用 Spring Boot 2.7.x 系列作为基础版本搭配 MyBatis-Plus 操作数据库前端使用 Thymeleaf 模板引擎 Bootstrap 搭建页面数据库选用 MySQL。这套组合是当前国内 Java 学习圈最常见的技术路线网上资料多、遇到问题容易搜到答案对新手极其友好。Spring Boot 的核心优势在于“约定优于配置”它已经帮你把 MVC、Jackson、日志、连接池这些基础组件都配置好了你只需要关注自己的业务代码。1.3 分层结构与工程目录设计拿到源码后第一件事先看包结构。这套项目遵循标准的 Controller → Service → Mapper 三层架构外加 entity实体类、config配置类、common通用返回与工具类。目录划分大概是这样的com.example.blog ├── controller // 控制层接收请求、返回视图或数据 ├── service // 业务层处理核心逻辑 ├── mapper // 数据访问层MyBatis-Plus 的 Mapper 接口 ├── entity // 数据库实体类 ├── config // 配置类如拦截器、WebMvc 配置 └── common // 统一返回结果、异常处理、分页封装这样的分层看似朴素但逻辑边界非常清晰Controller 不写业务Service 不碰 SQLMapper 只做数据读写。新人最容易犯的毛病就是在一个方法里把请求解析、业务处理、数据库操作全堆在一起当时觉得很爽后期改一个需求能把自己绕晕。分层的目的不是代码量变多而是让每一层都能独立测试、独立替换这也是以后进公司写真实项目时的基本素养。2. 核心功能模块拆解与实现要点2.1 文章管理模块Markdown 编写与展示链路文章是博客的核心资产这个模块的设计直接决定用户体验和后台操作的顺畅度。文章表的字段设计要兼顾展示和检索常见的字段包括主键 id、标题 title、摘要 summary、正文内容 content、封面图 cover、分类 id、创建时间、更新时间、浏览量、是否置顶、是否发布。正文存储格式这里要说明白项目中建议正文以 Markdown 原文存库页面展示时再做渲染。为什么要这么做因为 Markdown 是纯文本方便编辑、方便迁移也方便做全文检索而如果直接存渲染后的 HTML后续想换主题或改样式就非常被动。实现上前端编辑器可以使用 Editor.md国内很流行的开源 Markdown 编辑器它自带预览功能后端渲染可以用 commonmark-java 库。核心链路是管理员在后台用 Editor.md 编写并预览 → 表单提交 Markdown 源码到后端 → 存入数据库 → 访客访问文章详情页时后端将 Markdown 渲染成 HTML 再交给 Thymeleaf 模板展示。注意渲染一定要做在服务端不要把 Markdown 原文直接通过 Thymeleaf 的th:utext输出那样会有 XSS 风险——如果用户可以在内容里插入恶意 script危害很大。使用专门的安全渲染库虽然不能说 100% 免疫所有攻击但至少能过滤掉最常见的那批危险标签。2.2 分类与标签两种维度管理文章的差别分类和标签本质上都是给文章分组的但设计上有讲究。分类一般是单层、一对多的关系一篇文章属于一个分类一个分类下有多篇文章用category_id字段挂在文章表上即可标签则是多对多关系一篇文章可以打多个标签一个标签可以对应多篇文章必须用中间表article_tag来维护关联。表结构设计如下category表id,name,descriptiontag表id,namearticle_tag中间表article_id,tag_id不要嫌中间表麻烦。如果图省事把标签存成一个以逗号分隔的字符串字段刚开始确实方便但等你要做“点击标签查看所有相关文章”的时候就得用模糊匹配去捞数据这种 SQL 在数据量上来之后效率非常差而且完全没法做关联统计。中间表虽然多一张表但查询逻辑一目了然后期加功能也容易这个设计债不能欠。查询标签相关的文章时可以用 MyBatis-Plus 的 QueryWrapper 先查到文章 id 列表再回表查文章详情数据量大一点也可以写自定义 SQL 用 JOIN 一次查出。建议后者因为少一次回环SQL 执行计划也更可控这也是看讲解视频时要重点理解的地方。2.3 评论模块从表设计到防刷的简单处理评论是博客互动的重要组成部分设计时要把“游客可评论”和“管理员可删评”这两个需求考虑进去。评论表核心字段有id,article_id,nickname,email,content,parent_id,created_at。这里parent_id是为了支持楼中楼回复顶级评论该字段为 0回复某条评论时记录它的 id前端展示时按层次渲染。评论提交做两道防线就够了。第一道是后端校验内容不能为空、长度限制在合理范围比如 200 字以内、昵称不能带 HTML 标签。第二道是时间校验用 Session 记录用户上次评论时间两次评论间隔小于 30 秒就直接拒绝这能挡住大批脚本刷评论的请求。这里有个容易忽略的点评论内容在展示到页面上之前一定要做 HTML 转义把、转成实体字符否则别人在评论区写一段script你整个站就沦陷了。Thymeleaf 默认的th:text本身就带转义但如果你手痒用了th:utext就等于亲手把后门打开了。这种低级错误在真实项目中出过太多事故了务必重视。2.4 后台认证与拦截器实现博客后台不能裸奔必须做登录认证。这套项目的处理方式不复杂——登录成功后把管理员信息放进 Session同时定义一个拦截器对/admin/**路径下的请求做拦截未登录一律重定向到登录页。拦截器里实现HandlerInterceptor接口在preHandle里检查 Session 是否存在管理员标识。实际写拦截器时有两个容易踩的坑。第一个是拦截范围别把静态资源也拦了CSS、JS、图片这些资源路径要记得在配置里排除否则页面加载时样式全丢给人感觉项目坏了。第二个是登录请求本身不能被拦/admin/login这个路径必须放行否则永远进不了登录页死循环。如果想让项目更有练习价值可以把逻辑再升级一层登录成功后生成一个 Token用 Redis 存储并设置过期时间前端每次请求把 Token 放在 Header 里拦截器里核对 Token。这种方案代表了无状态登录的基本思路今后接触 Spring Security 或 JWT 时会更容易理解。不过对于当前这套个人博客系统Session 方案已经足够加了 Redis 反而让项目复杂度上升除非你想把它作为二次开发的一个练手方向。3. 环境准备与项目运行实操3.1 本地开发环境的版本匹配建议很多人在“跑不起来”这一步就放弃了原因多半是环境版本不匹配。这里先给出一套经过验证的本地环境组合组件推荐版本说明JDKJDK 8 或 11对应 Spring Boot 2.7.x兼容性最好Maven3.6.3 及以上版本别太老依赖下载会出问题MySQL5.7 或 8.05.7 更稳定8.0 需要调整时区配置IDEA2022 及以上对 Spring Boot 和 Maven 支持更友好Navicat / DataGrip任意版本用于可视化导入 SQL特别强调 JDK 和 Spring Boot 的对应关系。Spring Boot 2.7.x 用 JDK 8 编译运行是最稳的如果你把项目升级到 Spring Boot 3.x那 JDK 最低也要 17而且包名从javax换成了jakarta很多 import 语句要跟着改。这个问题在热词里有“springboot版本太高”这一条真实情况也是这样——不少人在 IDEA 里用 Spring Initializr 生成项目默认拉到了 3.x 版本结果 JDK 还是 8编译直接报错。所以拿到这套源码后先确认你本机的 JDK 版本再决定要不要动 Spring Boot 版本。MySQL 8.0 的时区问题也提一下连接 URL 里必须带serverTimezoneAsia/Shanghai否则驱动会报时区异常。很多新手在这一步栽跟头其实不是代码问题就是配置缺了参数。3.2 数据库初始化与配置文件修改源码里通常会附带一个blog.sql脚本里面建好了所有表还预置了管理员的账号密码一般是默认的 admin / admin123首次登录后记得改。用 Navicat 或命令行执行source blog.sql就能完成初始化。关键配置集中在src/main/resources/application.yml里需要改的地方就三处server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/blog?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver换成本机的数据库账号密码就完事了。有一点注意MySQL 5.7 的驱动类可以写com.mysql.jdbc.Driver但 MySQL 8.0 建议用com.mysql.cj.jdbc.Driver两者兼容性有细微差别统一用新版驱动类最省心。3.3 从源码到跑起来的完整步骤整个启动流程我建议按这个顺序操作可以少走很多弯路用 IDEA 的Open功能选择源码目录选择 Maven 项目导入等待依赖下载完成。如果 IDEA 提示 Maven 未配置先在File → Settings → Build Tools → Maven里配置好本地仓库路径。打开blog.sql在本地 MySQL 中执行建库建表。修改application.yml中的数据库账号密码确认端口没有被占用。找到启动类BlogApplication.java右键运行。控制台出现Started BlogApplication in x.x seconds字样后浏览器访问http://localhost:8080。访问http://localhost:8080/admin进入后台登录页用默认账号登录创建第一篇文章。整个过程如果顺利五六分钟就能跑起来。但这些步骤里随便哪一步不对报错信息都能让新手懵半天——这正是运行视频存在的意义它会把每一步的鼠标操作和界面反馈都录进去卡住了对着视频逐帧比对就行。3.4 运行视频里不会讲的几个启动细节有些细节运行视频往往一带而过但实际影响很大。第一IDEA 首次导入 Maven 项目时右下角会提示是否自动导入一定要选开启不然后面改pom.xml里的依赖不会自动更新。第二如果依赖下载慢在 Maven 的settings.xml里配置阿里云镜像这能省一大半时间。第三启动失败时别只看红色的异常堆栈先看最下面一行Caused by:的内容那才是真正的根因。还有一个非常容易忽略的点确认本机 8080 端口没被其他程序占用。Windows 下用netstat -ano | findstr 8080查一下如果被占用直接把application.yml里的端口改成 8081 或其他可用端口就行不需要和别人抢。4. 常见问题排查与避坑指南4.1 Spring Boot 版本太高引发的兼容性问题前面提过的“springboot版本太高”是绝对的高频坑这里展开说。如果你在 IDEA 新建项目时直接选了 Spring Boot 3.x或者把原有项目升级了会碰到三类典型报错javax.servlet找不到Spring Boot 3.x 把 JavaEE 标准换成了 Jakarta EE所有javax.*包名要改成jakarta.*。涉及面很广包括HttpServletRequest、ServletContext等手动改起来很麻烦。JDK 版本不兼容Spring Boot 3.x 要求 JDK 17 以上如果你本机只有 JDK 8编译阶段直接失败。部分第三方组件不支持比如比较老的 MyBatis-Plus 版本在 Spring Boot 3.x 下会启动失败需要换成对应适配版本。所以我的建议很简单这套个人博客系统用 Spring Boot 2.7.x JDK 8 是最稳的组合别追求版本新。新版本带来的特性在这个项目里基本用不上反而徒增兼容性风险。真正理解 Spring Boot 的核心思想之后再玩 3.x心态和排查能力都完全不一样了。4.2 数据库连接报错排查实录数据库相关的报错占了新手问题的一半以上。最经典的几种情况Access denied for user rootlocalhost账号密码错了或者 root 只允许 localhost 连接。检查application.yml里的 username 和 password。Unknown database blogSQL 脚本没执行成功或者库名写错了。用 Navicat 连上 MySQL确认左边能看到 blog 库和里面的表。The server time zone value ... is unrecognized连接 URL 没加serverTimezoneAsia/Shanghai加上就好。Public Key Retrieval is not allowedMySQL 8.0 的配置问题在连接 URL 后面追加allowPublicKeyRetrievaltrue。这些报错看着吓人其实都是配置层面的小事。排查时养成一个习惯先确认数据库能通过 Navicat 正常连接再确认账号密码是复制粘贴的而不是手敲的手敲容易把字母 O 和数字 0 搞混最后再看 Spring Boot 的具体异常信息。4.3 页面样式丢失与静态资源 404系统跑起来后页面能用但样式全是裸的这通常是静态资源配置或拦截器的问题。Spring Boot 默认的静态资源路径是classpath:/static/HTML 里引用的 CSS 路径要写相对路径或带上下文路径。如果配置了拦截器检查是否把/css/**、/js/**、/images/**这些静态资源路径放行了。经验之谈拦截器配置里宁可多放行也不要少放行比如/static/**、/webjars/**这些常见前缀漏一个就掉一个样式的坑。还有一个隐蔽问题Thymeleaf 模板路径写错不会立即报错而是页面渲染时出现 404 或空白。比如{}表达式引用路径不对资源找不到只是静默失败。排查时按 F12 打开开发者工具看 Network 面板红色请求对应的就是缺失的资源。4.4 常见问题速查表现象大概率原因快速解决办法项目启动报Port 8080 was already in use端口被占用换个端口或杀掉占用进程编译报cannot find symbol: class HttpServletRequest包名或版本不匹配确认是 Spring Boot 2.x 还是 3.x调整 JDK 版本访问/admin一直跳登录页登录状态没写入 Session核对登录逻辑看 Session 存储的用户标识首页能开但图片全部裂开静态资源路径问题检查图片路径和上传目录配置中文乱码编码不一致数据库连接 URL 加characterEncodingutf-8文件存为 UTF-8Markdown 内容显示成纯文本没有渲染确认后端是否正确调用渲染组件转成 HTML这张表基本覆盖了我见过的 90% 的启动和运行期问题建议收藏。项目遇到问题时先对着表自查一遍往往比自己瞎改半天有效。5. 源码阅读路线与二次开发扩展建议5.1 一份源码应该按什么顺序去读拿到源码别打开 IDEA 就乱翻容易越看越迷茫。我推荐的阅读顺序是先跑起来 → 再看数据库表 → 再读包结构 → 再按功能链路读代码。具体一点你可以从一个完整的请求入口开始顺藤摸瓜。比如“管理员在后台编辑一篇文章并保存”这个操作找到AdminArticleController看它接收了哪个请求路径和参数。进入ArticleService的保存方法看它做了哪些校验和组装。看ArticleMapper的插入或更新 SQL理解数据库层面的变化。跟着这样的链路走完两三个功能之后你会发现整套代码其实就是“请求进来 → 控制器收参数 → 服务层处理 → 数据层存取”的循环。所谓讲解视频核心价值就在这里——它把这条主线路径直接给你画好了配合源码读起来效率翻倍。5.2 二次开发值得动手的 4 个方向博客系统跑通只是起点真正提升能力的是二次开发。我根据实际经验给你排了四个由易到难的方向接入 Redis 做文章浏览量缓存每次访问文章都更新数据库的浏览量字段数据量大了会频繁触发写操作。用 Redis 先做计数定时同步回 MySQL这是一个非常经典且实用的缓存练习。全文搜索改造现在的搜索大概率是LIKE %keyword%数据量一大就慢。试试给文章标题建全文索引或者引入 Elasticsearch 做搜索服务后者算是架构层面的升级。第三方登录后台登录改成支持 GitHub / Gitee OAuth 授权登录。这个功能在企业项目中非常常见做完以后你对 OAuth2.0 的理解就不是停留在概念上了。图片上传走 OSS把本地存储的图片改成上传到阿里云 OSS 或 MinIO涉及到签名生成、文件类型校验、访问域名配置等一系列实战问题。每个方向做完你都可以把效果和踩坑过程整理成一篇文章这本身就是对自己技术总结能力的一次锻炼。5.3 文档和视频的正确使用节奏配套的文档和视频很多人是拿到手就从头看到尾看完觉得都会了一动手还是不会。我建议反过来用先花十分钟自己尝试跑项目卡住了再对着运行视频找对应的操作步骤跑起来之后自己看代码看不懂的地方再到讲解视频里找对应片段。视频应该是“索引”而不是“替代”它帮你定位知识盲区但永远替代不了你自己敲代码和改 bug 的过程。还有一个使用技巧运行视频里如果用的数据库账号密码和你的本机不一样不要照着抄一定要改成你自己的。看着视频里没问题直接复制配置到自己的机器上就各种报错问题就出在这里。6. 最后分享一个自己的体会博客系统这种项目技术难度确实不高但它在学习路径上的价值被严重低估了。把一个博客从零做成能跑、能上线、能被人访问你经历的不只是写代码还有建表设计、配置管理、问题排查、部署发布这一整条真实项目的链条。我见过很多刷了几百道面试题的人面对“讲讲你做过的项目”这个问题支支吾吾就是因为从来没有完整地拥有过一个项目。如果你拿到这套源码我的建议是别急着收藏吃灰花一个周末的时间按文档跑起来按视频看一遍再按我上面说的链路跟读两三个核心功能最后动手改一个小功能——比如给文章加一个阅读时长估算。当你真正把别人的源码变成自己熟悉的东西时这个项目才算真正属于你了。以后再遇到什么大项目你会发现无非是多了一些业务复杂度和技术组件底层的分层思想、配置思路、排错路径都是一样的。