资讯详情

资讯详情

Spring Boot校园新闻管理系统毕业设计完整开发指南

校园新闻管理系统这个选题在 Java 后端方向的毕业设计里属于“经典款中的经典款”。它的好处很实在题目不难理解技术栈主流业务场景贴近校园生活评委一眼就能看懂系统在干嘛。基于 Java Spring Boot 来做这套系统刚好能覆盖 Web 开发的一整条链路——前端页面、后端接口、数据库建模、权限控制、状态流转、部署上线做完之后你对整个 Java Web 开发的流程会有非常具体的体感而不只是停留在“会写几个接口”的层面。这周有个学弟让我帮他过一遍这个项目的设计文档我才发现很多人拿到这个题目的第一反应是“不就是新闻的增删改查吗”然后直接开始写代码结果写到评论、审核、角色权限的时候就懵了。这篇文章我打算从需求分析开始把数据库设计、后端实现、前端联调、部署上线到答辩准备全部串一遍每个环节都给你可以直接抄作业的思路和代码。不管你打算用 Thymeleaf 做服务端渲染还是用 Vue 做前后端分离这篇文章都能让你少踩不少坑。1. 需求分析与功能拆解先把系统会碰到的角色和流程理清楚1.1 三种角色与两条核心业务流做校园新闻管理系统第一步不是建表不是写 pom.xml而是先把“谁在用这个系统”和“系统里会发生什么”说清楚。这个项目里我一般把用户分成三类普通用户学生、老师、新闻编辑、系统管理员。普通用户负责看新闻、搜新闻、评论和点赞新闻编辑通常是校报记者团或者院系宣传员负责写稿和投稿系统管理员则是整个系统的运营者掌握分类管理、新闻审核、用户管理这些后台权限。这里有一个很关键的设计校园新闻毕竟是代表学校发声的内容正式发布前必须经过管理员审核不能编辑写完就直接挂到首页。所以整个系统的核心业务流其实是两条第一条是内容生产流——“编辑写草稿 → 提交审核 → 管理员审核通过 → 新闻发布 → 管理员下架”第二条是互动消费流——“用户搜索/浏览新闻 → 点击查看详情 → 评论/点赞 → 浏览量累计”。这两条链路一条对应后台管理一条对应前台展示全部走通之后这个系统才是完整的而不是一堆孤立页面的拼凑。1.2 前台与后台的功能清单把角色和流程定下来之后功能模块就非常清楚了。我习惯在动手前先列一张表把自己要做的东西全部摊开避免写着写着漏了模块也方便后面排开发顺序。模块包含功能使用角色说明用户认证登录、注册、退出登录、密码加密所有用户推荐使用 BCrypt 加密明文密码在毕业设计里是硬伤新闻展示首页推荐、分类列表、新闻详情、站内搜索所有用户未登录也能浏览这是内容型网站的基本体验互动功能评论、回复、点赞、浏览量统计登录用户点赞必须做防重复否则答辩时点两次就露馅新闻管理新闻增删改查、提交审核、编辑草稿新闻编辑编辑只能维护自己的新闻看到自己提交的审核状态审核流程列表审核、通过/驳回、上下架系统管理员这是区分“CRUD 项目”和“管理系统”的核心模块分类管理分类增删改查、排序、启用禁用系统管理员分类变化频率低但要考虑删除时已有新闻怎么处理用户管理用户列表、禁用/启用、角色分配系统管理员可以简化但必须能禁用异常账号数据统计总新闻数、分类占比、最新审核动态系统管理员后台首页做个简单的仪表盘答辩演示效果好1.3 为什么要刻意设计一个“业务闭环”很多同学做毕设容易陷入“能跑就行”的心态结果论文只能写“实现了新闻的增删改查”答辩被老师一追问就直接卡壳。我建议哪怕时间再紧也要想办法把业务闭环做完整。所谓闭环就是让数据在系统里流动起来编辑投稿后台产生一条待审核新闻管理员审核后在首页可见用户看完会产生评论、点赞和浏览数据这些数据又回到后台成为运营依据。这一步不需要额外引入什么中间件只要在数据库表设计上把新闻表的状态字段、评论表的外键、点赞表的唯一索引设计好后端把状态流转的逻辑写严谨整个项目在老师眼里的完整度马上就不一样了。严格来说这套系统的最小可用版本其实就是两张表——用户表和新闻表但真正值得写进论文和讲给评委听的是后面慢慢补上的审核流程、互动逻辑和权限控制。2. 技术选型Spring Boot 之外的搭配不是越新越好2.1 后端选型ORM、鉴权与缓存怎么配后端框架基本没有悬念Java 后端毕业设计用 Spring Boot 是绝对主流。真正让人纠结的是围绕 Spring Boot 周边怎么选尤其是 ORM 和权限框架。ORM 方面我建议优先考虑 MyBatis-Plus。它比原生 MyBatis 省去了大量写 mapper XML 的功夫单表增删改查直接继承 BaseMapper条件查询用 LambdaQueryWrapper分页插件也内置好做毕设的效率高非常多。需要注意的是不要让 MyBatis-Plus 成为你的盲区。答辩时老师很可能问“MyBatis 的动态 SQL 你会不会写”这部分基础还是要补一补。鉴权方案是另一个容易纠结的点。Spring Security 功能强大但学习曲线陡峭对毕设来说很容易陷入配置地狱。实际带项目的过程中我一般推荐两条路线如果你对框架比较熟用 Sa-Token它把登录、踢人下线、权限注解都封装得很简洁集成的代码量小源码也不难读如果你想在答辩时多讲一点底层原理就手写 JWT 拦截器整个鉴权链路差不多一两百行代码就能讲清楚。两种方案都比 Spring Security 更适合“毕设交付”这个场景。2.2 前端选型Thymeleaf 还是 Vue取决于你的剩余时间前端部分到底用服务端渲染还是前后端分离本质上是时间预算问题。我列个表你直接对号入座方案优点缺点适合人群Thymeleaf Bootstrap不用处理跨域项目结构简单部署只打一个 jar页面交互体验一般前端展示效果不够“现代化”时间紧张后端基础一般求稳能跑通Vue3 Element Plus前后端分离页面美观交互流畅答辩演示效果好需要处理跨域、Token 存储、前端打包难度和工时都增加有前端基础想冲高分愿意多花时间原生 HTML jQuery简单直接代码混乱后期维护困难不推荐几乎无前端基础临时应付我自己带学生的时候通常建议如果毕设周期在三个月以上就顶住压力做 Vue Element Plus 的前后端分离学到的东西更多简历上也更好写如果只剩一个多月老老实实用 Thymeleaf Bootstrap先把业务闭环跑通前端展示用一套现成的后台管理模板效果也不会差。2.3 项目结构与版本依赖参考无论选哪种前端方案后端项目的目录结构都建议规范一些。我常用的分包方式是标准的三层架构加一个 config 包src/main/java/com/example/campusnews/ ├── config/ # 配置类跨域、拦截器、MyBatis-Plus 分页插件 ├── controller/ # 控制层接收请求、参数校验、返回 Result ├── service/ # 业务逻辑层包括接口和实现类 ├── mapper/ # 数据访问层MyBatis-Plus 的 Mapper 接口 ├── entity/ # 数据库实体类 ├── dto/ # 前端入参对象用于接收请求参数 ├── vo/ # 视图对象用于返回给前端的结构 ├── common/ # 通用类Result、异常类、常量、枚举 └── util/ # 工具类JWT 工具、日期工具等版本方面这里直接给一套我验证过的组合JDK 8 或 11 Spring Boot 2.7.x MyBatis-Plus 3.5.x MySQL 8.0。如果学校要求 JDK 17可以上 Spring Boot 3.x但要注意 3.x 里 javax 包名变成了 jakarta有些老教程里的代码需要改 import。能用 2.7 就用 2.7省掉这些兼容问题。集成测试时你会发现这套组合非常成熟网上基本能搜到所有踩坑记录。3. 数据库设计五张核心表撑起整个系统3.1 核心表结构说明数据库设计是这个项目的地基很多同学一上来就建表结果字段名不规范、类型选错后面写代码全是坑。校园新闻管理系统正常情况只需要五张核心表系统用户表、新闻分类表、新闻信息表、评论表和点赞表。如果还想要操作日志、消息通知这类功能再加表也不迟但最核心的业务五张表就够了。先明确一下每张表的关键职责。用户表除了登录认证字段还要有角色字段和状态字段新闻表承担的是最重的业务逻辑除了标题、正文、封面图这些内容字段一定要设计好分类外键、作者外键和状态字段评论表通过新闻外键和用户外键关联内容父评论 ID 字段用于支持楼层回复点赞表的结构非常简单核心是建一个联合唯一索引防止重复点赞。3.2 建表 SQL 与字段设计要点下面是核心表的建表 SQL我精简了主要字段你直接拿去改成自己项目的表名前缀就行-- 用户表 CREATE TABLE sys_user ( id bigint 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 昵称, avatar varchar(255) DEFAULT NULL COMMENT 头像地址, role tinyint NOT NULL DEFAULT 1 COMMENT 角色 1普通 2编辑 3管理员, status tinyint NOT NULL DEFAULT 1 COMMENT 状态 1正常 0禁用, create_time datetime DEFAULT NULL COMMENT 创建时间, update_time datetime DEFAULT NULL COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT系统用户表;-- 新闻表 CREATE TABLE news ( id bigint NOT NULL AUTO_INCREMENT COMMENT 新闻ID, category_id bigint NOT NULL COMMENT 分类ID, title varchar(100) NOT NULL COMMENT 新闻标题, summary varchar(255) DEFAULT NULL COMMENT 摘要, content longtext COMMENT 正文内容, cover_image varchar(255) DEFAULT NULL COMMENT 封面图, author_id bigint NOT NULL COMMENT 作者ID, author_name varchar(50) DEFAULT NULL COMMENT 作者昵称(冗余), status tinyint NOT NULL DEFAULT 0 COMMENT 状态 0草稿 1待审核 2已发布 3已下架, view_count int NOT NULL DEFAULT 0 COMMENT 浏览量, like_count int NOT NULL DEFAULT 0 COMMENT 点赞数, comment_count int NOT NULL DEFAULT 0 COMMENT 评论数, is_top tinyint NOT NULL DEFAULT 0 COMMENT 是否置顶, publish_time datetime DEFAULT NULL COMMENT 发布时间, create_time datetime DEFAULT NULL COMMENT 创建时间, update_time datetime DEFAULT NULL COMMENT 更新时间, PRIMARY KEY (id), KEY idx_category (category_id), KEY idx_status_publish (status, publish_time) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT新闻信息表;这里有几个很关键的细节。第一content 字段用 longtext新闻正文如果是富文本长度可能会比较长varchar 撑不住。第二status 字段是整个系统的状态机核心建议用 tinyint 加注释代码里再定义一个枚举类对应避免全项目到处写魔法数字。第三作者昵称是冗余字段因为用户表里可能会改昵称新闻列表页直接用 news 表里的 author_name 就能显示不需要每次 JOIN 用户表性能更好即使用户改名也不会影响历史新闻的显示。点赞表和评论表也一并给出-- 评论表 CREATE TABLE news_comment ( id bigint NOT NULL AUTO_INCREMENT COMMENT 评论ID, news_id bigint NOT NULL COMMENT 新闻ID, user_id bigint NOT NULL COMMENT 评论用户ID, parent_id bigint NOT NULL DEFAULT 0 COMMENT 父评论ID0表示顶级评论, content varchar(500) NOT NULL COMMENT 评论内容, status tinyint NOT NULL DEFAULT 1 COMMENT 状态 1正常 0删除, create_time datetime DEFAULT NULL, PRIMARY KEY (id), KEY idx_news (news_id, create_time) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT新闻评论表;-- 点赞表 CREATE TABLE news_like ( id bigint NOT NULL AUTO_INCREMENT COMMENT 点赞ID, news_id bigint NOT NULL COMMENT 新闻ID, user_id bigint NOT NULL COMMENT 用户ID, create_time datetime DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uk_news_user (news_id, user_id) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT点赞表;点赞表的联合唯一索引 uk_news_user 是最关键的设计它是防重复点赞的最终兜底。哪怕你的代码里并发判断出了纰漏数据库这一层也会把重复插入直接拦截掉只需要在业务代码里捕获 DuplicateKeyException 然后返回“您已经点过赞了”即可。3.3 冗余字段、逻辑外键与自动填充写清楚了 SQL 再聊聊设计心得。第一我设计的表基本都不加物理外键。外键看似能保证数据完整性但实际开发里它会带来很多麻烦删除新闻时要先删评论删除分类时要处理关联新闻测试数据清理起来非常痛苦。我更推荐用逻辑外键也就是只保留关联字段加上普通索引在代码里保证引用的正确性。这更贴近企业里的实际开发习惯。第二create_time 和 update_time 这种公共字段不需要在每一处代码里手动 set。MyBatis-Plus 提供了 MetaObjectHandler 自动填充机制只需要在实体类字段上加 TableField(fill FieldFill.INSERT) 注解然后写一个处理器统一填充创建时间和更新时间。另外表名我用的是小写下划线实体类用驼峰命名配置 mybatis-plus 的 map-underscore-to-camel-case 默认开启即可自动映射。做项目时最好一开始就把这些公共约定定好避免后面切库或者换人接手时一地鸡毛。4. 后端实现从登录认证到新闻状态机的完整落地4.1 统一返回体与全局异常处理后端代码的第一个基础设施是统一返回体 Result 类。它的作用是把成功、失败、未登录、无权限等各种情况包装成固定结构前端处理起来才不用东猜西猜。下面是我常用的模板Data public class ResultT { private Integer code; // 200成功 401未登录 403无权限 500异常 private String message; private T data; public static T ResultT ok(T data) { ResultT r new Result(); r.code 200; r.message 操作成功; r.data data; return r; } public static T ResultT fail(Integer code, String message) { ResultT r new Result(); r.code code; r.message message; return r; } }配合 Result 类一定要写全局异常处理。用 RestControllerAdvice 捕获业务异常、参数校验异常和兜底异常否则一旦代码抛了 NPE前端看到的就是整页又长又难看的报错信息。业务异常建议定义一个 BizExceptionService 层判断不合法时直接 throw new BizException(新闻不存在)全局处理器负责把 message 转成 Result 返回。这样一个约定下来后面写所有接口都会快很多。4.2 登录认证与接口权限控制登录认证这一块如果你选择手写 JWT核心流程是这样的用户登录成功后用用户 ID、角色和过期时间生成 token 返回给前端前端后续请求在请求头里带上 Authorization: Bearer token后端写一个拦截器对需要认证的接口先解析 token再把用户信息放到 ThreadLocal 里供后续使用。这个方案核心代码量不大关键是拦截器注册和放行路径要配置清楚。如果你用 Sa-Token代码就更简洁了PostMapping(/login) public ResultString login(RequestBody LoginDTO dto) { User user userService.findByUsername(dto.getUsername()); if (user null || !BCrypt.matches(dto.getPassword(), user.getPassword())) { return Result.fail(500, 用户名或密码错误); } if (user.getStatus() 0) { return Result.fail(500, 账号已被禁用); } StpUtil.login(user.getId()); // 把角色写入 Sa-Token 的权限体系 StpUtil.getSession().set(role, user.getRole()); return Result.ok(StpUtil.getTokenValue()); }接口权限控制建议按角色严格区分。后台管理相关的接口全部要管理员角色用户中心相关的接口要登录才能访问新闻浏览接口直接放行。前端再配合按钮级隐藏普通用户即使猜到后台 URL后端也会拦下来。这是答辩时最容易被追问的点你哪怕实现得很简单也要把这条链路讲清楚。4.3 新闻审核状态机的关键代码新闻审核是整个项目里最有业务深度的部分也是我把前面数据库状态字段落到实处的关键。新闻状态定义为0 草稿、1 待审核、2 已发布、3 已下架。编辑保存新闻时为草稿点击提交后变成待审核管理员在待审核列表中点击通过变成已发布点击驳回则回到草稿或标记为已驳回已发布的新闻可以下架下架后可以重新发布也可以修改后再次走审核流程。审核接口的实现核心在于状态校验不能把“任何状态”都允许切换到“任何状态”Transactional(rollbackFor Exception.class) public void audit(Long newsId, Integer pass) { News news newsMapper.selectById(newsId); if (news null) { throw new BizException(新闻不存在); } if (news.getStatus() ! NewsStatus.PENDING.getCode()) { throw new BizException(当前状态不可审核请刷新后重试); } if (pass 1) { news.setStatus(NewsStatus.PUBLISHED.getCode()); news.setPublishTime(LocalDateTime.now()); } else { news.setStatus(NewsStatus.DRAFT.getCode()); } newsMapper.updateById(news); }这里有两个细节值得写进论文一是 setPublishTime 只在审核通过时赋值不要用数据库的默认时间否则草稿期就把发布时间写进去了二是接口必须加 Transactional 事务注解状态更新是单表 update 虽然简单但养成事务习惯对后面做多表操作非常重要。4.4 点赞防重、评论列表和浏览量统计的实现细节点赞接口是防重设计的最佳练兵场。完整实现分三步先通过 uk_news_user 联合唯一索引判断记录是否存在不存在就插入同时给新闻表的 like_count 加一如果插入时抛出 DuplicateKeyException说明并发情况下重复点了直接捕获异常返回提示。还要考虑一个边界情况用户点了赞之后能不能取消这个完全看你设计需求如果要支持取消点赞删除 news_like 记录并给 like_count 减一即可。这里不能直接 update news 表里的 like_count而是应该用 update news set like_count like_count 1避免先查后改的并发覆盖问题。评论列表查询时我建议前端详情页直接拉两级结构顶级评论按时间排序每条新闻最多显示前几页回复评论通过 parent_id 关联。列表查询用一个 JOIN 把评论用户头像和昵称带出来避免在循环里一条条查用户表这种 N1 查询是新手最容易犯的性能错误。浏览量统计在这个量级的项目中不需要额外引入中间件详情页打开时执行一条 update news set view_count view_count 1 就足够了配合置顶状态和发布时间做列表排序业务上很够用。5. 前端页面与交互落地从首页展示到后台管理5.1 前台首页和新闻详情页的关键处理前台首页是整个系统的门面信息架构上一般分四大块顶部导航栏分类菜单 搜索框、轮播推荐区置顶新闻或重点新闻、分类新闻列表按栏目展示最新几条、热门排行按浏览量排序。用 Thymeleaf 做的时候可以直接在 Controller 里查好数据塞进 Model然后通过 thymeleaf 的 each 循环渲染用 Vue 分离做的时候就定义好几个接口返回 JSON前端按接口拼数据。新闻详情页是整个系统里接口最集中的一个页面。进入详情页时要调用详情接口返回新闻正文、作者信息、浏览量正文渲染时最需要注意的是 XSS 安全问题如果是富文本编辑器上传的内容后端必须对 script 标签做过滤可以引入 jsoup 设置白名单只保留 p、img、h2、h3 这类安全标签。点赞按钮和评论列表的加载都要基于登录状态做判断未登录用户点击点赞应该提示“请先登录”评论框也不要展示成可输入状态。5.2 后台管理界面的布局与状态联动后台管理前端可以直接用一套现成的模板比如 AdminLTE 或者自己写个简单的侧边栏加内容区布局。左侧放菜单仪表盘、新闻管理、审核管理、分类管理、用户管理。右侧内容区用表格展示数据每一个业务操作按钮都要和新闻的状态联动待审核的新闻显示“通过/驳回”按钮已发布的显示“下架”已下架的显示“重新发布”草稿状态的显示“编辑/提交审核”。这个“按钮跟着状态走”的逻辑比把所有按钮都堆上去要合理得多答辩演示的时候观感会好很多。如果你做前后端分离联调时有两个地方容易卡壳跨域和 Token。跨域在开发环境可以通过 Vue CLI 的 devServer proxy 代理解决后端加一个 CORS 配置类也行但上线后还是建议用 Nginx 做反向代理把 /api 路径转发到后端服务这样浏览器里就只有一个同源地址不会出跨域问题。Token 的存储一般放 localStorage请求拦截器里统一带 Authorization 头遇到 401 状态码就跳转登录页。5.3 站内搜索、富文本编辑器和图片上传的坑站内搜索最简单可靠的实现是 SQL like 加 concat 拼接查标题、摘要、正文三个字段然后用发布时间倒序。查询的关键是判断关键字是否为空以及用 #{} 占位符防 SQL 注入。对于毕设来说 MySQL 的 like 已经足够真到了数据量大那一天再考虑 Elasticsearch 也不迟。如果你想让性能好看一点可以给新闻表的 title 字段建一个普通索引并解释一下“前置通配符会导致索引失效”这个面试点。富文本编辑器我推荐 wangEditor 或者类似的开源编辑器轻量且文档齐全。这里最大的坑是图片上传。编辑器里粘贴的图片如果直接以 base64 形式存进长文本一条新闻的 content 能上几万字符数据库压力很大页面加载也会变慢。正确做法是单独写一个文件上传接口前端编辑器配置好图片上传回调上传成功后将服务器返回的图片 URL 插入到正文中。项目里静态资源文件路径要单独配置一般放在本机某个目录或部署时用 Nginx 映射到一个 /uploads 路径。6. 本地运行、服务器部署与答辩准备6.1 从零把项目跑起来你拿到这套系统之后最优先的任务是把它在本地跑起来。准备工作就四步安装 JDK、Maven、MySQL 和 IDE。JDK 版本按你项目实际用的来如果 Spring Boot 2.7 用 JDK 8 就行。MySQL 建议 8.0 以上在数据库中执行建表脚本把五张核心表建好顺便插入初始化数据——比如设置一个管理员账号、几个新闻分类、三五条演示新闻、一些测试评论切到后台页面时就不用现场编数据了。接着修改 application.yml 里边的数据库连接地址、账号、密码连接串记得带上 useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai不然会出现中文乱码和日期时区报错。启动主类浏览器访问 8080 端口能进首页基本就成功了。整个过程中如果遇到端口被占用改一下 server.port 即可这个问题在答辩现场的电脑上经常出现提前弄清楚怎么换端口很重要。6.2 打包部署到服务器的简化方案本地跑通之后如果想让老师通过公网或者校园网访问就需要部署。简化方案是打包成 jar 文件然后放到一台装有 JDK 的服务器上运行。打包这里用 Maven 命令就可以mvn clean package -DskipTests打包完成后target 目录下会生成一个 jar 文件把它上传到服务器执行下面的命令就能后台启动nohup java -jar campus-news-0.0.1.jar app.log 21 第一次访问服务器时记得确认服务器安全组或防火墙放行了对应端口。更稳妥的做法是在 jar 前面加一层 NginxNginx 监听 80 端口把请求代理到本机 8080 端口同时把 /uploads 静态目录也交给 Nginx 管理。这样的部署架构虽然简单但已经很接近真实企业项目的形态了写进论文里是加分项。6.3 把这个项目变成面试和答辩素材的方法项目做完了剩下的就是“讲故事”。我平时跟学生强调最多的一个观点是你做的每一个功能都要能回答“为什么”三个字。比如 Spring Boot 为什么能简化开发因为它约定大于配置、自动装配、内嵌容器。新闻列表的分页查询用了什么MyBatis-Plus 分页插件底层就是拦截器加 SQL 改写。登录为什么用 JWT因为它无状态、适合前后端分离场景。这些概念就是 Java 面试里常见的基础问题你把它们和这个项目绑定在一起记忆面试时就不是背八股文而是讲真实经历。答辩高频追问我也提前给你梳理几个方向正文富文本如何防 XSS、点赞防重怎么保证并发安全、浏览量一小时内被刷一万次怎么办、用户越权访问后台接口如何拦截。针对这些问题你只要把安全过滤、唯一索引、事务回滚、角色校验这几个关键词准备好再结合代码回答基本都能过关。很多同学觉得八股文和做项目是两回事其实做完这个项目你就会发现八股文里讲的概念几乎全都能在项目里找到实例。7. 常见问题排查启动、数据访问和业务逻辑的 12 个坑7.1 启动失败类问题症状可能原因解决办法启动报端口被占用8080 端口被其他程序使用改 server.port或找到占用进程杀掉启动报 Access denied for user数据库账号密码错误检查 application.yml 的账号和权限启动报 Unknown database数据库没有创建或库名不匹配先执行 CREATE DATABASE再确认连接串库名启动报时区错误MySQL 连接 URL 缺少时区参数连接串加 serverTimezoneAsia/ShanghaiMaven 依赖下载缓慢或者报红默认中央仓库访问慢配置阿里云镜像仓库重新导入依赖7.2 数据访问类问题Mapper 接口已经写了启动却报找不到扫描对象一般是没加 MapperScan 或者没在接口上加 Mapper 注解。MyBatis-Plus 写了分页查询但分页不生效这是最容易漏掉的一环——新版 MyBatis-Plus 分页必须配置 PaginationInnerInterceptor 插件不配置的话你的 Page 参数会被当成普通条件。中文乱码问题的根源通常有两个数据库连接 URL 没加 characterEncoding或者数据库表本身建成了 latin1 字符集。顺手检查一遍这三处数据访问的坑基本都能解决。7.3 业务逻辑类问题点赞接口第一次点成功第二次还能点检查一下点赞表的唯一索引有没有真的建上代码里先查再插和唯一索引必须两个都做。评论删除后新闻的评论数不变因为你的删除逻辑只删了评论记录没有去更新 news 表的 comment_count这个字段属于冗余计数删除时必须同时处理。富文本编辑器上传的图片在新闻详情页打不开大概率是图片上传保存的是本地绝对路径详情页访问时 Nginx 或者静态资源映射没配置对应目录后台管理界面里通过相对路径访问一次就能验证。7.4 安全与细节问题安全方面的坑每个都值得单独强调。密码一定不要明文存库用 BCrypt 加密这个没有例外。SQL 写法的原则是能用 #{} 就不要用 ${}前者是预编译占位符后者是字符串拼接后者有 SQL 注入风险。富文本内容上传到数据库之前听过一遍 XSS 过滤尤其是 script 标签和 onerror 事件。后台管理接口要有角色校验哪怕前端已经隐藏了管理入口后端接口没有鉴权一样会被 URL 扫描器发现。最后提醒一个小细节错误提示不要太详细不然等于把系统内部结构告诉了攻击者生产环境里异常信息统一返回“系统繁忙请稍后重试”就够了。这个项目我前后陪着很多学生完整做过最大的感受是真正让你和普通 CRUD 项目拉开差距的从来不是用了多冷门的技术而是你把需求分析做到多细、把状态流转做得多严谨、把防重和权限设计想得多全面。最后分享一个答辩实用技巧开场不要急着打开系统点来点去先花三分钟把业务闭环讲清楚——谁投稿、谁审核、谁消费、数据如何回流——然后再演示对应功能。评委听到你有清晰的业务设计思路再看代码里状态机、唯一索引、统一异常处理这些都落到了实处分数自然就上去了。你做完这套系统之后后续可以试着把新闻分类扩展成多级栏目或者给编辑加一个个人投稿数据看板这个项目还能延伸出很多有趣的方向。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →