首页 / 资讯中心 / 文章详情

基于Java的个人博客系统毕设:Spring Boot+MyBatis架构与部署答辩全攻略

基于Java的个人博客系统毕设:Spring Boot+MyBatis架构与部署答辩全攻略 ★ FEATURED ARTICLE
简介一份基于Java的个人博客系统毕业设计全套资料包面向计算机相关专业毕业生与Java Web初学者可覆盖选题、开发、文档整理与答辩展示的完整需求尤其适合需要从零搭建完整项目的学习者。压缩包大小178.52MB内含项目报告、答辩PPT、源代码、数据库文件与部署教程视频对应需求分析、系统设计、模块划分、接口定义、数据表结构及核心编码实现等核心资料。技术栈涉及Servlet、JSP、JavaBean、MySQL等后端与数据库技术以及HTML、CSS、JavaScript、Bootstrap等前端技术代码分层清晰便于理解MVC架构下的控制层、业务层与持久层。目前已有1347人浏览学习适合作为毕业设计参考和Java Web实战练习。通过部署视频可快速完成环境配置、数据库导入与项目启动配合答辩PPT和项目报告能直观呈现系统功能与设计思路帮助学习者少走弯路并提升工程实践能力尤其对系统测试与部署环节可提供直接参照。1. 基于 Java 的个人博客系统毕业设计这份资源能帮你省掉哪一段路每年毕设季问得最多的就是「有没有一个能直接跑的 Java 项目」这套基于 Java 的个人博客系统毕业设计资源包——项目报告 答辩 PPT 源代码 数据库 部署视频——就是冲着这个需求来的。它的价值不是让你什么都不干而是把搭框架、建库、配环境的几周时间压缩成几天把精力留给真正要命的事看懂表结构、改出自己讲得明白的代码、练到敢现场演示。适合 Java 方向学生、想快速交差的初级开发者以及用博客练 Spring Boot 的入门选手。下面我按「架构立住 → 跑起来 → 改得动 → 扛住答辩」的顺序把这套资源吃透。2. 把博客毕设拆开看技术选型、表结构与文档框架先立住2.1 为什么是 Spring Boot MyBatis选型理由要能扛住答辩提问拿到源码第一步不是跑而是先搞清楚它为什么长这样。常见的 Java 个人博客模板有两类老一点的是 SSMSpring Spring MVC MyBatis新一点的是 Spring Boot MyBatis 或 Spring Boot JPA。现在的主流是 Spring Boot 2.x MyBatis理由很实际Spring Boot 内嵌 Tomcat、自动配置数据源、打 jar 直接跑省去 SSM 那一大堆 XML 配置MyBatis 的 SQL 是自己写的映射关系直观答辩时随便问一句「你的查询怎么写」你能当场说出 SQL 而不是解释一个黑匣子。为什么不用 JPA毕设规模下 JPA 的自动建表和懒加载反而是负担尤其是多表关联时 Hibernate 的 N1 查询问题讲不清楚容易翻车。MyBatis 加一个 MyBatis-Plus 的 BaseMapper单表增删改查几乎不用写 SQL代码量砍一半。模板引擎这边老项目用 JSP 的不少但现在答辩老师普遍反感 JSP 的部署方式——改一个页面要重新编译。我一般建议认准 Thymeleaf后端渲染、天然支持 Spring Boot、改页面只要改模板文件刷新浏览器就能看到效果。前后端分离的 Vue REST 方案在工程上是更现代的但对毕设来说要额外处理跨域、Token、前端打包演示环境一多踩坑成本翻倍。2.2 五张核心表文章、分类、标签、评论、用户的关系一次理清数据库是整个项目里最值得花时间搞懂的部分。一个标准的 Java 个人博客系统表结构逃不出这五张用户表、文章表、分类表、标签表、评论表加上一张文章和标签的多对多关联表。先建库再建表。下面是完整可执行的 MySQL 脚本我按通常的模板写法给你拆开。-- 用户表 CREATE TABLE t_user ( id INT NOT NULL AUTO_INCREMENT COMMENT 用户ID, username VARCHAR(50) NOT NULL COMMENT 登录名, password VARCHAR(100) NOT NULL COMMENT 密码推荐BCrypt密文, nickname VARCHAR(50) DEFAULT NULL COMMENT 显示昵称, role TINYINT NOT NULL DEFAULT 1 COMMENT 权限1管理员 0普通用户, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;-- 文章表 CREATE TABLE t_article ( id INT NOT NULL AUTO_INCREMENT COMMENT 文章ID, title VARCHAR(200) NOT NULL COMMENT 标题, summary VARCHAR(500) DEFAULT NULL COMMENT 摘要, content LONGTEXT NOT NULL COMMENT 正文存HTML或Markdown, category_id INT DEFAULT NULL COMMENT 所属分类ID, user_id INT NOT NULL COMMENT 作者ID, view_count INT NOT NULL DEFAULT 0 COMMENT 浏览量, status TINYINT NOT NULL DEFAULT 0 COMMENT 0草稿 1已发布, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_category (category_id), KEY idx_user (user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT文章表;-- 分类表 / 标签表 / 评论表 CREATE TABLE t_category ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_name (name) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT分类表; CREATE TABLE t_tag ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT标签表; CREATE TABLE t_comment ( id INT NOT NULL AUTO_INCREMENT, article_id INT NOT NULL COMMENT 文章ID, user_id INT DEFAULT NULL COMMENT 评论人ID游客为NULL, content VARCHAR(1000) NOT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_article (article_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT评论表;-- 文章-标签关联表 CREATE TABLE t_article_tag ( article_id INT NOT NULL, tag_id INT NOT NULL, PRIMARY KEY (article_id, tag_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT文章标签关联表;几个参数你答辩时最好能主动讲出来。第一engineInnoDB支持事务和行级锁博客这种读写混合的小项目足够第二charsetutf8mb4而不是utf8因为表情符号也要入库utf8 存不下 emoji 会直接报错第三create_time用DEFAULT CURRENT_TIMESTAMP插入时不用手动塞时间第四外键我建议不建物理外键只建普通索引因为物理外键在删除分类或用户时会连锁报错毕设阶段用逻辑关联在代码层控制就够了。第五t_article_tag这种关联表的主键用的是联合主键防止同一篇文章打同一个标签两遍。2.3 项目报告和答辩 PPT三块内容决定你是 60 分还是 90 分源码再漂亮报告和 PPT 写不明白照样被卡。我的经验是无论模板里原本写了什么你至少要在这三块上投入时间。第一块是需求分析和用例图别写「本系统实现了用户管理」这种废话要写「管理员可以发布、编辑、删除文章游客可以按分类和标签浏览文章并发表评论」每个角色配两三个典型流程。第二块是系统设计把架构图画成三层控制层Controller、业务层Service、数据访问层Mapper再把 2.2 里的 ER 图贴上去标注主键、外键和一对多关系。第三块是测试结果除了功能测试用例表强烈建议放两三个接口测试截图——用 Postman 调 /article/list、/admin/article/save 这些接口把返回 JSON 贴进 PPT比十页功能截图都有说服力。文档这块有个常见翻车点直接从别的毕设复制需求分析导致「系统角色」还留着根本没实现的后台评论审核功能。答辩老师对项目里没有的东西问得最狠。我建议对着自己的功能清单一项项核报告里出现的每个功能代码里必须能找到对应入口代码里有的功能报告里必须有截图。能做到这个闭环答辩基本就稳了。3. 从源码到跑起来部署视频没拍全的关键步骤与参数3.1 环境准备JDK、Maven、MySQL 的版本匹配关系部署视频通常会快进这段但环境不匹配是「跑不起来」的第一大原因这不是玄学是版本兼容问题。先把三个版本对清楚再动手。java -version mvn -version mysql --version三条命令分别查 JDK、Maven 和 MySQL 的版本。常见的 Java 个人博客模板对应的是 JDK 1.8 Maven 3.6 MySQL 5.7 或 8.0。如果你电脑上装的是 JDK 17直接跑 Spring Boot 2.x 老模板启动时大概率报UnsupportedClassVersionError或者 CGLIB 相关错误因为新版 JDK 移除了部分反射权限。两个处理办法一是装一个 JDK 1.8 并在 IDEA 的 Project Structure 里切过去二是把 pom.xml 里的 Spring Boot 版本升到 2.7 以上同时检查 MyBatis 和 Thymeleaf 的兼容性。我一般倾向第一种成本最低也最贴近模板原作者的运行环境。MySQL 这块注意一个小细节5.7 和 8.0 的驱动类名不一样。5.7 用com.mysql.jdbc.Driver8.0 用com.mysql.cj.jdbc.Driver而且 8.0 的连接 URL 必须带时区参数不然报Communications link failure。下面配置章节我会把标准写法给出来。如果你用 IDEA直接把源码目录当 Maven 项目导入等依赖下载完成src/main/java下的启动类会有一个绿色的运行按钮点了就能起——但先别急数据库还没导。3.2 导入数据库先建库再导数据别跳过 charset资源包里通常会有一个.sql文件可能是blog.sql或database.sql。导入前先做一件事打开看看文件开头有没有CREATE DATABASE语句。有的话直接一条命令全导没有的话先建库再导。mysql -u root -p -e CREATE DATABASE IF NOT EXISTS blog DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; mysql -u root -p blog blog.sql第一行创建名为 blog 的数据库DEFAULT CHARSET 和 COLLATE 必须显式指定因为有些 MySQL 服务器的默认字符集是 latin1表即使写了 utf8mb4建库这一步兜底错了后面查中文会乱码。第二行把 SQL 文件导入到 blog 库。成功后执行mysql -u root -p -e USE blog; SHOW TABLES;能看到 t_user、t_article 这些表就对了。还有一坑有些模板的 SQL 文件里已经写了USE blog;但你本地库名不叫 blog 叫 blog_system导入时就会把数据写进它指定的库你的配置文件却连着一个空库。遇到这种情况要么建一个和文件里同名的库要么把 SQL 文件里的USE语句注释掉再导入。导入完了顺手查一下 t_user 表有没有初始账号数据没有的话自己插入一条管理员账号密码先用最简单的 123456登录跑通后再改。3.3 application.yml 的五个必调参数改错一个就起不来源码里在src/main/resources下找到application.yml或application.properties。Spring Boot 2.x 模板基本都用 yml 格式层次比 properties 清楚。下面是按标准写法给出的最小可用配置server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/blog?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你自己的密码 driver-class-name: com.mysql.cj.jdbc.Driver thymeleaf: cache: false mybatis-plus: mapper-locations: classpath:mapper/*.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl五个重点逐一说明。第一server.port改 8080 以外要保证没被占用。第二URL 里serverTimezoneAsia/Shanghai是 MySQL 8.0 的必填项缺了直接连接失败。第三characterEncodingutf8配合数据库的 utf8mb4 保证中文不乱码URL 里的useUnicodetrue也顺手留着。第四spring.thymeleaf.cache: false是开发期福利改 HTML 模板不重启就能看到效果如果设成 true你改了首页死活没变化就是这个在作怪。第五log-impl配成 StdOutImpl 后每次 SQL 执行都会打印到控制台调试和答辩排错都靠它。密码字段提醒一句本地开发可以明文但不要把这个配置提交到公开的 GitHub 仓库源代码管理里把配置文件的敏感信息替换成环境变量是基本素质。3.4 本地启动和打包mvn 两种方式的区别环境配好、库导好、配置改好就可以启动了。IDEA 里直接点运行最省事但更推荐命令行方式因为你以后要写部署文档里面所有命令必须是命令行可执行的。mvn spring-boot:run这是开发模式前台运行按 CtrlC 结束日志实时滚。适合本地调代码。mvn clean package -DskipTests java -jar target/blog-0.0.1-SNAPSHOT.jar这是生产模式先跳过测试打包成 jar再java -jar跑起来。打包完你会发现 target 目录下多了个几十 MB 的 jar里面带着内嵌 Tomcat扔到任何装了 JDK 的机器上都能起这才是部署视频里常说的「可执行文件」。启动日志里看到Tomcat started on port(s): 8080就成功了浏览器访问http://localhost:8080如果能打开首页整个链路就算跑通。接着做两件事登录后台然后发一篇测试文章确认数据库的增删改查都是好的。到这一步你已经完成了这段毕设最「虚」但最容易卡住的环节。4. 源码骨架怎么读、怎么改核心模块的套路和必调参数4.1 登录与权限拦截器是最适合毕设的轻量方案把项目跑起来后就该打开源码认真读了。我不建议一开始就从 controller 逐行看而是先顺着一个请求走完你的登录请求是怎么进到后台的大多数个人博客模板用的是拦截器方案而不是 Spring Security因为后者的过滤器链、UserDetailsService、权限配置对毕设来说太重讲不清楚还容易出配置问题。拦截器的实现就是一个类加一段注册代码。Component public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object loginUser request.getSession().getAttribute(loginUser); if (loginUser null) { response.sendRedirect(/admin/login); return false; } return true; } }Configuration public class WebConfig implements WebMvcConfigurer { Resource private LoginInterceptor loginInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns(/admin/**) .excludePathPatterns(/admin/login, /admin/doLogin, /css/**, /js/**, /images/**); } }这段逻辑的关键在excludePathPatterns登录接口和静态资源必须放行否则样式全丢、登录接口也进不去。真实模板中这几个放行路径经常写漏写错表现为「登录成功了但后台页面没有样式」八成是/css/**这类没放行或者 JSP 老模板把静态资源放在 webapp 下导致路径对不上。读取请求处理流程时顺带把登录密码的校验方式看一眼。好的模板会存 BCrypt 密文答辩时可以主动提一句「密码不是明文存储用的 BCrypt 加盐哈希」。如果你的模板是明文存密码我建议改掉在 Service 里用BCryptPasswordEncoder的matches方法做校验改动量不大但这是答辩老师最喜欢的细节之一。4.2 文章增删改查MyBatis-Plus 让代码少写一半文章模块是个人博客系统的核心你要能讲清楚「新增一篇文章从页面到数据库走过了什么」。常见模板的 Mapper 层写法是 MyBatis-Plus 风格接口长这样public interface ArticleMapper extends BaseMapperArticle { }你没看错空接口就够了。BaseMapperT内置了insert、deleteById、updateById、selectById、selectList等十几个通用方法单表 CRUD 零 SQL。真正需要写条件查询的地方用的是LambdaQueryWrapper比如后台分页查文章列表Override public PageArticle pageArticles(int pageNum, int pageSize, String keyword, Long categoryId) { LambdaQueryWrapperArticle wrapper new LambdaQueryWrapper(); wrapper.like(StringUtils.hasText(keyword), Article::getTitle, keyword) .eq(categoryId ! null, Article::getCategoryId, categoryId) .orderByDesc(Article::getCreateTime); return articleMapper.selectPage(new Page(pageNum, pageSize), wrapper); }参数说明like和eq的第一个参数是布尔条件为 true 时该条件才生效这样搜索框没填关键词时就自动跳过模糊查询不需要手动写三个 if。Article::getTitle是方法引用MyBatis-Plus 靠它解析成数据库字段名避免了硬编码字符串导致改字段名后 SQL 崩掉。selectPage的返回值Page里带着records当前页数据、total总条数、current当前页码、size每页条数前端遍历records分页组件读这四个属性就够。答辩时老师常追问「分页怎么实现的」你要能答出两层应用层用 Page 对象传页码和每页大小MyBatis-Plus 底层自动拼接LIMITMySQL或ROWNUMOracle语句数据库层返回当页数据而不是全表。如果你的模板不是 MyBatis-Plus 而是纯 MyBatis 的 XML 写法也没问题去src/main/resources/mapper/下打开 ArticleMapper.xml你会看到selectPageByCondition这类手写 SQL那里才是你真正要读的地方。4.3 前端 Thymeleaf三个必改页面和它们的属性套路前端模板页在src/main/resources/templates/下常见结构是index.html前台首页、article.html文章详情、admin/后台管理。Thymeleaf 的语法核心就是th:属性看懂了下面这段首页列表其他页面都是变体ul li th:eacharticle, stat : ${page.records} a th:href{/article/{id}(id${article.id})} th:text${article.title}文章标题/a span th:text${#dates.format(article.createTime, yyyy-MM-dd)}发布日期/span em th:text共 ${article.viewCount} 次浏览浏览量/em /li /ulth:each是循环page.records对应 Controller 放进 Model 的分页数据stat是循环计数器可以取stat.index拿序号。th:href的{/article/{id}(id${article.id})}是带参数的 URL 写法比字符串拼接安全自动做 URL 编码。th:text输出纯文本如果文章正文存的是 HTML详情页要用th:utext输出否则标签会被转义成文字显示。这是毕设里出现频率最高的 bug正文全部变成了带p标签的源码就是因为用了th:text。改前端时两条血泪经验第一页面里的静态资源路径一律用th:href{/css/style.css}别在 HTML 里手写/css/style.css否则项目部署到子路径时全部 404第二后台表单提交改成 POST 后Controller 要加PostMapping并处理重定向表单验证出错时用BindingResult把错误信息回显到页面。你把这些点改过一遍源码就算是真正读懂了。5. 部署与答辩避坑高频翻车现象、原因与排查方法5.1 数据库连不上时区、编码、未建库三类报错现象一启动日志报Communications link failure或The server time zone value Öйú±ê׼ʱ¼ä is unrecognized。原因MySQL 8.0 要求连接串显式指定时区而配置里没带serverTimezone。解决在application.yml的 URL 末尾加上serverTimezoneAsia/Shanghai重启。现象二控制台报Unknown database blog。原因SQL 文件没导入或者导入时库名和连接串不一致。解决按 3.2 的命令重新建库导入然后确认配置文件里的库名和实际库名一字不差。注意大小写MySQL 在 Linux 下表名库名是区分大小写的。现象三中文乱码页面上全是???。原因建库时没指定utf8mb4或者 JDBC URL 少了characterEncodingutf8。解决把库、表、连接串三级全部统一成utf8mb4 / utf8改完重新启动并刷新页面。这三个问题占了「数据库连不上」九成以上任何一个都可以在答辩现场直接让你翻车提前用上面的命令自查一遍。5.2 端口被占用和项目起不来现象启动日志有Port 8080 was already in use。原因之前运行的后台程序没退干净或者本地有其他服务占了 8080。排查命令# Windows 查看占用 8080 的进程 netstat -ano | findstr 8080 taskkill /PID 你的进程号 /F # macOS / Linux lsof -i :8080 kill -9 你的进程号杀掉进程后重启即可。另一个起不来的场景是java -jar启动后访问 404原因多半是模板引擎页面路径不对——Thymeleaf 默认去templates/下找 HTML如果你的页面放到了static/下Controller 返回的视图名永远找不到控制台还会打一行Circular view path [index]的警告。解决是确认视图名和templates/下的文件名完全一致区分大小写。5.3 打包后资源丢失和静态 404现象IDEA 里运行一切正常按 3.4 打包成 jar 后再访问发现 CSS、JS 全部 404。原因打包时资源文件没被包含进 jar或者代码里用了硬编码路径。解决打开pom.xml确认build段里有resources配置把src/main/resources纳入打包然后把页面里的/css/xx.css全部改成th:href动态写法重新mvn clean package。这个坑几乎人人都踩提前踩完部署演示时就多一分从容。还有个冷门但常发生的SQL 文件没被包进 jar。如果你的初始化 SQL 放在resources/sql/下而 pom 没包含**/*.sql部署到新机器上就会「有代码没数据」。解决是在resources配置里加一条include**/*.sql/include或者干脆把 SQL 文件和 jar 放在一起手动导入。5.4 答辩演示前的四个准备动作演示翻车往往不是技术问题是流程问题。第一准备一个专用演示账号并确认密码正确不要现场输密码手一抖就完蛋。第二预置演示数据至少 5 篇文章、3 个分类、4 个标签、2 条评论别打开后台发现是空库。第三把log-impl的 SQL 日志留着演示时故意操作一次新增文章让控制台滚出INSERT INTO语句这是证明「你懂底层」的现场证据。第四断网检查——如果页面里引用了外部 CDN 的图标或字体答辩教室没网时页面会很难看提前把静态资源本地化。这四条做完心态上已经赢了七成。5.5 初始账号找不到模板最容易被忽略的坑现象数据库导入成功但登录页面输什么密码都报错。原因SQL 文件里的初始用户表数据有但密码是加密串你输的 123456 明文自然匹配不上。解决找到项目里处理登录的 Service看它用的是 BCrypt、MD5 还是别的算法如果是 BCrypt去在线生成器把 123456 加密后 UPDATE 进用户表如果是 MD5同样生成密文后更新。这条我建议无论如何都提前做好因为它是「看起来全对但就是进不去」的典型黑匣子问题也是我见过导致答辩现场直接断片的头号原因。6. 让毕设从「能跑」到「能加分」三个进阶方向与一个验证方法基础功能全通后你有余力就可以往加分项上走优先级按投入产出比排。第一个是 Markdown 富文本编辑把文章 content 字段存 Markdown 源文展示时用 commonmark-java 库渲染成 HTML改动只涉及编辑页和详情页两个地方答辩却能讲出「编辑器层和数据展示层分离」的设计思想。第二个是全文搜索别自己用LIKE %keyword%硬扛数据量大了性能断崖直接给文章表加 MySQL 全文索引用MATCH(title, content) AGAINST(关键词)查询一句话就能讲清楚「数据库级的全文检索方案」。第三个是图片上传。给后台加一个图片上传接口存储到本地目录再把访问路径映射成虚拟 URL。这个功能几乎每个答辩老师都会问「你的图片存哪」你能答出「服务器目录 虚拟映射 数据库存路径」三层比答「存数据库」高一截。验证方法用一条命令就能完成。启动服务后用 curl 连打三个接口验证核心链路curl -X POST http://localhost:8080/admin/doLogin -d usernameadminpassword123456 curl http://localhost:8080/article/list?pageNum1pageSize5 curl -X POST http://localhost:8080/admin/article/save -d title测试content内容categoryId1第一条看登录是否返回成功第二条看列表是否返回 JSON第三条写一条测试数据后去数据库里查SELECT * FROM t_article ORDER BY id DESC LIMIT 1;确认落库成功。这三步做完你的毕设从代码、数据到部署就是一条完整的、经得起验证的链路。我个人的习惯是每次改完代码都跑一遍这三条命令确认没有「改一处崩三处」。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站