ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Spring Boot+MyBatis在线答疑系统开发实战:从设计到部署

Spring Boot+MyBatis在线答疑系统开发实战:从设计到部署 简介在Java Web开发中Spring Boot凭借自动配置和内置容器成为构建业务系统的主流框架其核心价值在于简化工程搭建让开发者聚焦于业务逻辑。结合MyBatis与MySQL可以高效实现数据持久化与查询优化形成一套经典的业务开发链路。在线答疑系统作为典型的教育互动场景天然包含用户权限控制、问题发布、回答采纳、积分统计等完整业务闭环是Web开发进阶的理想实践。围绕该系统本文从选题价值与技术选型切入阐述数据库表结构设计、核心模块实现思路、分页与事务处理方案并针对环境配置、中文乱码、端口占用等常见问题给出排查技巧。通过实际项目演示帮助读者掌握从需求拆分到部署上线的完整流程为毕业设计或工程实践提供可复用的参考方案。 聊个接地气的话题。每年毕业季Java方向的毕设题目翻来覆去就是管理系统、商城、论坛这几类而“在线答疑系统”算是在其中比较耐打的一个。它在难度上正好卡在“管理系统”和“互联网应用”中间既有用户身份、权限控制又有提问、回答、采纳这种典型互动业务流而且天然带一个“搜索”场景能覆盖到 Spring Boot 项目里最常用的几块技术。做完这个题目你不仅能把 springboot、MyBatis、MySQL 这一整条链路彻底串起来还说得出每一步的业务逻辑而不是像很多管理系统那样只是对着数据表写 CRUD。这篇文章就把这个在线答疑系统的设计思路、数据库建模、核心模块实现、部署踩坑全过一遍。源码加论文加 PPT 加视频的项目包结构我会按“先拆业务、再讲技术、最后带你跑起来”的方式来聊。不管你是刚学完 Java 基础准备拿这个项目练手还是准备直接拿去当毕设主体按这个思路走一遍心里都会踏实很多。1. 选题价值与整体设计思路1.1 为什么推荐在线答疑系统作为毕设题目大部分人选毕设题目有个误区觉得越复杂越好。实际上毕业设计的核心评分点在于“功能完整、业务闭环、答辩能说清楚”。在线答疑系统的受众很明确就是学生和老师这类教育场景下的用户业务链条非常自然学生遇到问题后发布提问其他同学或老师看到后进行回答提问者可以采纳满意的答案系统再结合用户行为做一些积分和统计。整个流程没有生搬硬套的痕迹每一步都能自圆其说。这个题目比普通管理系统更有看点的地方在于业务角色多。普通管理系统通常就管理员一个角色在操作在线答疑系统天然有学生、老师、管理员三类角色权限控制的代码自然就有了用武之地。内容互动性强。提问、回答、评论、点赞、收藏、采纳这些都是典型的“用户对用户”的交互行为非常契合现在互联网产品的形态。数据量有想象空间。问题表、回答表会随时间增长搜索和分页的优化点顺理成章地出现答辩时候能聊的东西就多了。1.2 系统架构与核心业务流程整个项目前后端不分离Spring Boot 负责接口和页面渲染MySQL 存数据模板引擎输出页面这是一套非常标准的服务端渲染架构。很多毕设项目会把前后端分离当成加分项但对于一个在线答疑系统来说如果目标只是完整跑起来并顺利答辩服务端渲染反而更稳妥——少了一层联调少了一堆跨域问题代码量也更可控。核心流程可以用一条主线串起来用户注册登录 - 发布问题 - 系统展示问题列表 - 其他用户浏览并回答 - 提问者采纳最佳答案 - 系统更新积分状态 - 管理员后台管理异常内容在这个链路里每一个环节都对应着一个数据库操作和一组页面。选题的时候想清楚这条主线后面写代码就顺了。最怕的就是一开始没想明白写到一半发现答非所问、功能之间互相卡壳返工成本极高。1.3 功能模块拆分与边界划分按角色切分系统可以拆成三块游客端只能浏览问题列表和问题详情能看到回答但没登录不能提问、不能回答。这块代码量不大但是“拦截器 登录态校验”的典型场景。学生/老师端登录后可以发布问题、回答问题、评论、点赞、收藏、采纳答案。学生和老师的区别主要在于积分规则和数据查看权限例如老师可以删除违规回答学生没有这个权限。管理端主要是内容审核和用户管理。管理员可以禁用用户、删除违规问题、管理问题分类、查看统计数据。从开发角度看建议按“用户模块 - 问题模块 - 回答模块 - 互动模块 - 后台管理模块”的顺序逐层推进。先解决“谁能登录”的问题再解决“能发什么”的问题然后解决“能回答什么”的问题最后把辅助功能补齐。这样的顺序每一阶段都有可运行的结果调试起来很舒服。2. 技术选型与工具链解析2.1 为什么选 Spring Boot 而不是传统 Spring MVC这里要说一个很多人容易忽略的点。传统 SSMSpring Spring MVC MyBatis项目要做大量的 XML 配置数据源、事务管理器、视图解析器、扫描包路径每一样都要手工写而且不同版本之间配置还不一样非常折磨人。Spring Boot 的核心优势在于自动配置它通过spring-boot-starter-*系列依赖把各种能力打包好你用的时候只需要引入依赖再配上少量配置项框架就会自动装配好底层组件。举个例子你用传统 Spring MVC 要连数据库得自己去配DataSource、配SqlSessionFactory、配事务管理器用 Spring Boot 只需要在pom.xml里加上spring-boot-starter-jdbc或mybatis-spring-boot-starter然后在application.yml里写四行数据库连接信息就够了。这套“约定优于配置”的思想对毕设项目来说就是巨大利好——你不必被繁琐的装配过程劝退可以把精力放在业务代码本身上。另外Spring Boot 内置了 Tomcat打包成可执行的 Jar 包就能直接跑部署成本极低。答辩的时候可以在现场直接java -jar启动比在 IDEA 里点好几次配置才能跑起来要省心得多。2.2 数据库与 ORM 方案对比数据存储这块MySQL 是绝对的主流选择社区资料多、中文文档全、出问题一搜就有答案。如果你本机装的是 8.0 版本注意驱动配置和连接串写法跟 5.x 略有不同。ORM 层有两条技术路线之争一个是 MyBatis一个是 Spring Data JPA。这里按毕设场景给你列个对比表对比维度MyBatisSpring Data JPASQL 控制力手写 SQL完全可控由框架自动生成复杂查询需要 JPQL学习成本中等会 SQL 就能上手偏高需要理解对象关系映射思想动态 SQL支持灵活的动态 SQL 拼接需要 Specification 或 QueryDSL较繁琐中文资料量非常多较多排错难度SQL 报错直观Hibernate 生成的 SQL 不直观排错相对困难答辩可聊性可以聊 SQL 优化、索引设计可以聊 ORM 原理和缓存机制我的建议是用 MyBatis或用 MyBatis-Plus。原因很简单毕设答辩时老师一定会问“你的数据库查询是怎么实现的”如果你用的是 MyBatis可以直接把 SQL 拿出来分析还能聊聊为什么加索引、为什么用模糊查询、怎么分页如果是 Spring Data JPA你很难三言两语把 Hibernate 的内部机制讲清楚容易被追问到死角。2.3 前端方案与页面渲染方式在线答疑系统这种项目页面数量不算少但每个页面都不复杂无非是列表页、详情页、表单页、个人中心页。使用 Thymeleaf 作为服务端模板引擎是最稳妥的路线因为它是 Spring Boot 官方推荐的方案和 Spring Boot 的整合几乎没有额外成本页面里可以直接写 HTML 标签也能在模板里嵌入服务端数据。如果你非要上 Vue 做前后端分离也不是不行但你要考虑一个问题这类项目一旦前后端分离你至少要多维护一套登录凭证、一套跨域配置、一套接口文档而且答辩时候老师大概率会追问“token 怎么存”“刷新 token 怎么处理”这类框架层面问题准备不足容易被问住。服务端渲染则把这些问题天然简化了——用户的登录状态存放在 Session 中拦截器统一校验逻辑清晰几句话就能说清楚。这里也提一句静态资源。答疑系统的富文本编辑器、Markdown 渲染建议直接用现成的开源库如 wangEditor、editormd不要去自己实现编辑器。把精力省下来放在核心业务逻辑上才是性价比最高的做法。2.4 开发环境与版本选择版本选择是很多新手踩坑的重灾区。Spring Boot 的版本跨度很大从 1.x 到现在的 3.x不同版本对 JDK 和依赖的要求差异明显。当前主流的中文教程和大部分毕设项目都基于 Spring Boot 2.x推荐使用 2.7.x 版本原因有几个2.7.x 是 2.x 系列的最终版本稳定性很高社区资料也最丰富。2.7.x 默认支持 JDK 8 和 JDK 11而绝大多数学校的实验环境、答辩电脑上装的就是 JDK 8。3.x 版本强制要求 JDK 17虽然新但很多第三方库的兼容版本跟进得并不到位第一次上手容易遇到各种莫名其妙的报错。数据库方面MySQL 5.7 或 8.0 都行本地如果已经有环境不必刻意降级。IDEA 用 2021 之后的版本即可Maven 用 3.6.3 或 3.8.x。这些版本组合经过大量项目验证兼容性最好。3. 数据库设计与核心表结构实现3.1 数据模型总览在线答疑系统的核心数据实体有用户、问题分类、问题、回答、问题评论、点赞记录、收藏记录、操作日志。下面给出核心表的字段设计思路并附上可直接执行的建表 SQL。这里以 MySQL 8.0 为例字符集使用utf8mb4排序规则使用utf8mb4_general_ci这样能正确存储中文和 emoji 字符。3.2 用户表与问题分类表用户表是整个系统的地基。字段设计上除了基本的账号密码外一定要考虑到用户角色学生、老师、管理员、用户状态正常、禁用、积分字段和头像。密码存储不建议用明文哪怕毕设项目也要用MD5或BCrypt做一次哈希处理这不光是为了安全也是答辩时的一个加分点。CREATE TABLE user ( id bigint NOT NULL AUTO_INCREMENT COMMENT 主键ID, username varchar(64) NOT NULL COMMENT 登录用户名, password varchar(128) NOT NULL COMMENT 密码加密存储, nickname varchar(64) DEFAULT NULL COMMENT 昵称, avatar varchar(255) DEFAULT NULL COMMENT 头像URL, role tinyint NOT NULL DEFAULT 1 COMMENT 角色1-学生 2-老师 3-管理员, status tinyint NOT NULL DEFAULT 1 COMMENT 状态1-正常 0-禁用, points int NOT NULL DEFAULT 0 COMMENT 积分, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;问题分类表比较简单就是id、分类名称、排序号、创建时间几个字段。分类不需要设计成多级一级分类对这个系统来说完全够用没必要为了炫技引入“无限级分类”的复杂度。3.3 问题表与回答表设计问题表是核心业务表。标题要限制长度内容使用TEXT类型status字段用来标记问题的状态待回答、已解决、已关闭、已删除。这里的关键设计点是accepted_answer_id它记录被采纳的回答 ID通过这个字段能把问题和最佳答案关联起来。同时还要记录发布者 ID、所属分类 ID、浏览数、回答数这些统计字段在列表页展示时非常重要。CREATE TABLE question ( id bigint NOT NULL AUTO_INCREMENT COMMENT 主键ID, user_id bigint NOT NULL COMMENT 提问用户ID, category_id bigint NOT NULL COMMENT 问题分类ID, title varchar(128) NOT NULL COMMENT 问题标题, content text NOT NULL COMMENT 问题详情, status tinyint NOT NULL DEFAULT 0 COMMENT 状态0-待解决 1-已解决 2-已关闭 3-已删除, view_count int NOT NULL DEFAULT 0 COMMENT 浏览次数, answer_count int NOT NULL DEFAULT 0 COMMENT 回答数量, accepted_answer_id bigint DEFAULT NULL COMMENT 采纳的回答ID, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), KEY idx_user_id (user_id), KEY idx_category_id (category_id), KEY idx_status_create_time (status, create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT问题表;回答表的结构相对简单核心字段就是问题 ID、回答用户 ID、回答内容、是否采纳。回答内容同样使用TEXT类型accepted字段虽然可以通过问题表里的accepted_answer_id推导出来但为了查询方便还是建议在回答表里冗余一个标志位。CREATE TABLE answer ( id bigint NOT NULL AUTO_INCREMENT COMMENT 主键ID, question_id bigint NOT NULL COMMENT 问题ID, user_id bigint NOT NULL COMMENT 回答用户ID, content text NOT NULL COMMENT 回答内容, accepted tinyint NOT NULL DEFAULT 0 COMMENT 是否采纳0-否 1-是, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), KEY idx_question_id (question_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT回答表;3.4 点赞、收藏与评论表点赞和收藏表属于典型的“关系型记录表”结构几乎一样。核心由操作人 ID 和目标 ID 组成加上一个唯一约束防止重复。这里有一个设计取舍点赞和收藏是建多张表还是用一张表通过类型字段区分从范式角度来说拆成两张表更好字段语义清晰索引也更容易设计。从省代码的角度也可以合并成一张“用户行为表”加一个type字段区分点赞、收藏、浏览。我个人建议拆成两张表因为未来统计点赞数和收藏数时SQL 写起来一眼就能看懂。评论表也类似关联目标类型问题或回答、评论内容、评论人。在线答疑系统里评论功能可以做也可以不做——如果你时间紧张可以先不做评论把回答和采纳功能做扎实毕竟答疑系统的核心价值在“问答”而不是“评论”。3.5 索引设计与性能考虑索引是答辩时最容易展开聊的技术点。这个项目里至少要考虑三类索引主键索引InnoDB 默认会基于主键构建聚簇索引所以每张表都必须有主键。唯一索引用户名、问题标题如果要求不重复这类业务字段用唯一索引兜底。普通索引外键字段如用户 ID、分类 ID以及排序查询字段如创建时间都应该加普通索引。这里特别注意idx_status_create_time这个联合索引。列表页最常见的查询是“查某一状态的问题并按创建时间倒序”联合索引(status, create_time)能直接覆盖这个查询场景避免文件排序。如果你写成(create_time, status)排序优化效果会打折扣。另外MySQL 的LIKE %关键词%无法走索引这是一个经典问题。毕业设计阶段直接用LIKE模糊查询完全没问题重要的是你需要在答辩时清晰地说明这个写法在小数据量下够用如果要支持更高效的中文检索可以引入全文索引或 Elasticsearch。知道“当前方案够用且能说清未来优化点”老师反而会认可。4. 核心业务模块实现与代码解析4.1 登录注册与权限拦截器这个模块的核心不是登录页面本身而是登录态的管理。Spring Boot 项目里最省事的做法就是用HttpSession保存用户信息然后写一个拦截器统一校验。这里分享一个基于 Session 的登录状态管理代码片段核心思路是用户登录成功后将用户对象放入 Session拦截器拦截需要登录的路径检查 Session 中是否存在用户如果不存在跳转到登录页。Component public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session request.getSession(); User loginUser (User) session.getAttribute(loginUser); if (loginUser null) { // 未登录重定向到登录页 response.sendRedirect(/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(/**) .excludePathPatterns(/login, /register, /css/**, /js/**, /img/**, /, /question/**); } }密码加密这块建议使用BCryptPasswordEncoder它比 MD5 安全得多Spring Security 框架自带的这个工具类可以单独拿出来用。虽然这个项目没有引入 Spring Security但引入它的加密工具类成本极低。4.2 问题发布与列表分页问题发布是一个表单提交动作。前端页面收集标题、分类、详细内容后端拿到数据后校验参数然后组装成Question实体插入数据库。参数校验可以用Validated注解配合注解校验也可以在后端手动判断。毕设项目手动判断就够了但要注意在 Service 层做校验而不是在 Controller 里这样代码结构更合理。列表分页是毕设项目的必考知识点。MyBatis 分页最省心的方法是使用PageHelper插件它通过拦截器改写 SQL自动生成LIMIT语句业务代码几乎不用改。使用方式如下PageHelper.startPage(pageNum, pageSize); ListQuestion list questionMapper.selectQuestionList(status); PageInfoQuestion pageInfo new PageInfo(list);PageHelper.startPage之后的第一个查询会被自动分页PageInfo里封装了总记录数、总页数、当前页等分页所需的所有信息前端用th:each遍历配合th:href拼接页码参数就可以完成整个分页功能。如果你希望手写 SQL 来体现功底也可以不用 PageHelper改为自己传pageNum和pageSize计算出offset后拼接LIMIT。两种方式都行我个人的建议是 PageHelper 更稳妥它可以让你把时间花在业务逻辑上而不是跟分页 SQL 的边界计算较劲。4.3 问答核心流程与采纳机制提问者采纳答案是这个系统最重要的业务闭环也是答辩时的亮点功能。业务规则是这样的只有提问者本人才能采纳回答一个问题只能采纳一个回答采纳后问题状态变为已解决回答者获得积分奖励。采纳操作的 Service 核心代码如下Transactional public void acceptAnswer(Long questionId, Long answerId, Long loginUserId) { Question question questionMapper.selectById(questionId); if (question null || !question.getUserId().equals(loginUserId)) { throw new BusinessException(无权操作); } if (question.getStatus() 1) { throw new BusinessException(该问题已解决); } Answer answer answerMapper.selectById(answerId); if (answer null || !answer.getQuestionId().equals(questionId)) { throw new BusinessException(回答不存在); } // 更新答案采纳状态 answerMapper.updateAccepted(answerId, 1); // 更新问题状态和采纳回答ID questionMapper.updateAcceptedInfo(questionId, answerId); // 给回答者加积分 questionMapper.increasePoints(answer.getUserId(), 10); }这段代码里有一个关键点Transactional事务注解。采纳操作涉及更新回答表、更新问题表、更新用户积分三个操作任何一个失败都应该整体回滚不能出现“问题已解决但答主没加分”这种数据不一致的情况。在答辩时主动提到事务老师会认为你对数据一致性有基本认识这是明显的加分项。4.4 搜索功能与个人中心搜索功能可以做成标题和内容的全表模糊查询用一条拼接的 SQL 搞定。为了展示搜索关键词在标题和内容中的匹配优先级可以在ORDER BY里用CASE WHEN做简单排序标题命中的排在前面内容命中的排在后面。个人中心则是一个信息聚合页显示我的提问列表、我的回答列表、我的收藏列表、我的积分、我的个人信息。这些数据本质上都是“按用户 ID 查询某个表”每个列表页写一个 Mapper 方法就够。可以给列表加一个 tab 切换前端用th:class实现当前 tab 的高亮效果后台用同一个 Controller 的不同方法返回同一个页面。5. 项目部署运行与打包上线5.1 本地开发环境搭建环境搭建是新手最容易卡住的环节。按照下面的步骤走二十分钟内应该能把项目跑起来。第一步安装 JDK 8 并配置环境变量。建议同时配置JAVA_HOME和PATH在命令行执行java -version能看到版本号就说明配置成功。这里有个容易被忽略的点IDEA 里配置的 JDK 路径和命令行里的 JDK 可能不是同一个注意在Project Structure里把 Project SDK 设置为本地 JDK。第二步安装 Maven 并配置settings.xml。国内环境下不配置阿里云镜像的话下载依赖会非常慢。在settings.xml的mirrors节点里加入阿里云公共仓库镜像下载速度会快几个数量级。第三步安装 MySQL创建数据库并导入项目自带的sql文件。注意数据库的字符集选utf8mb4避免后续插入中文数据出现乱码。5.2 核心配置项详解项目根目录下的application.yml是最重要的配置文件。一个典型的配置如下server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/online_answer?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 123456 thymeleaf: cache: false mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.onlineanswer.entity configuration: map-underscore-to-camel-case: truemap-underscore-to-camel-case: true这个配置建议务必打开否则数据库里user_id这种下划线字段映射到 Java 里的userId属性时会失败导致查询结果全是 null。这是毕设项目里最隐蔽也最常见的问题之一。thymeleaf.cache: false的意思是页面模板不做缓存你修改了 HTML 之后刷新页面就能看到效果开发调试体验会好很多。生产环境打包前再改回true也不迟。5.3 打包部署与常见启动方式毕业设计阶段部署不需要上服务器。最常见的场景是在答辩现场用自己的电脑演示或者把项目发给老师验收。如果是本机演示直接在 IDEA 里启动Application.java即可。千万别在答辩前临时用命令行启动因为你可能忘记application.yml里的数据库密码、端口配置是否和当前环境一致。如果项目要求可执行部署可以先用 Maven 打包成可执行 Jar 包mvn clean package -DskipTests打包成功后在项目target目录下会生成一个online-answer-0.0.1-SNAPSHOT.jar文件。命令行执行启动命令java -jar online-answer-0.0.1-SNAPSHOT.jar启动成功后浏览器访问http://localhost:8080就能看到系统首页。这里有个细节打包前务必确认数据库连接配置正确否则 Jar 包起来后连不上数据库页面会直接白屏报错。如果你对 Docker 有了解也可以写一个简单的Dockerfile把项目镜像化。这个不是毕设硬性要求但能写出来绝对是加分项说明你有工程化部署的基本意识。6. 常见问题与排查技巧6.1 启动报错端口被占用或版本不兼容每次帮人排查毕设项目问题遇到最多的就是启动阶段报错。这里列一个高频问题速查表报错现象可能原因解决方案Port 8080 was already in use本地 8080 端口被占用修改application.yml中的server.port或关闭占用进程Failed to configure a DataSource没有配置数据库连接信息检查application.yml中的 url、username、password 是否正确填写java.sql.SQLException: Access denied for user数据库用户名或密码错误用客户端工具测试连接确认账号权限Unknown database online_answer数据库不存在或名字拼错在 MySQL 中执行CREATE DATABASE online_answer DEFAULT CHARSET utf8mb4;Invalid bound statement (not found)Mapper XML 没扫到检查mybatis.mapper-locations配置和 XML 文件目录是否匹配Caused by: java.lang.UnsupportedClassVersionErrorJDK 版本与项目要求的版本不一致确认本地 JDK 为项目要求的版本推荐 JDK 8 或 11如果你是照着教程搭的环境报错顺序通常和上述表格中的顺序一致。处理思路也很简单从上往下检查优先排查环境和配置再排查代码问题。6.2 中文乱码与静态资源加载失败中文乱码是一个历史遗留问题排查三步走第一步检查数据库表是否使用utf8mb4字符集以及数据库连接串里是否写了characterEncodingutf8。第二步检查.java文件编码是否为 UTF-8。IDEA 默认是 UTF-8但如果用记事本修改过文件编码可能被改成 GBK。第三步检查前端页面meta标签和响应头是否声明了 UTF-8。静态资源CSS、JS、图片加载失败绝大多数情况是路径写错。Thymeleaf 页面里引用静态资源推荐使用th:href{/css/style.css}和th:src{/js/app.js}这样的写法它会自动拼接项目上下文路径避免手工拼接带来的路径错误。6.3 数据查询结果为空或字段映射为 null这个问题出现的概率非常高。很多人明明看到数据库里有数据查询接口也执行了 SQL但返回的对象全是 null。最常见的一个原因就是我在 5.2 里说的map-underscore-to-camel-case配置没开。另一个常见原因是表名和实体类名不一致。MySQL 在 Linux 环境下默认区分表名大小写Windows 环境下默认不区分如果你的实体类叫Question表却建成了question在 Windows 下大概率没问题但换到 Linux 部署时就会报“表不存在”的错误。建议统一使用小写表名Java 类名按驼峰命名配合 MyBatis 的驼峰映射配置一步到位。6.4 毕业设计答辩中的高频提问点答辩时老师一般不会关心你的代码写得有多炫更关注你“为什么这么做”和“遇到问题怎么解决”。建议提前准备这几个问题的答案为什么选择 Spring Boot答自动配置简化开发内置 Tomcat 便于部署生态成熟社区资料多。登录状态是怎么管理的答基于 Session用户登录后把用户信息放 Session通过拦截器校验未登录访问。密码为什么要加密存储答防止数据库泄露后账号被恶意使用使用 BCrypt 或 MD5 做单向哈希。分页是怎么实现的答使用 PageHelper 插件基于 MyBatis 拦截器自动拼接 LIMIT 语句。如果用户量增大系统哪里会成为瓶颈答数据库查询压力尤其是问题表的模糊搜索可以引入缓存和全文索引优化。这些问题都不难但需要你能顺着自己的代码讲出来。我的建议是答辩前把你写过的每个 Mapper 方法都打开看一遍想清楚每条 SQL 在做什么、为什么这么写基本上就能应对绝大多数追问。项目源码阅读与后续扩展建议最后分享一个很实用的源码阅读顺序。拿到这套项目包后不要急着打开浏览器点页面先按下面的顺序读代码先读pom.xml搞清楚项目引了哪些依赖形成技术栈的整体认知。再读application.yml理解项目启动需要哪些外部依赖数据库、端口、文件路径。然后找启动类看SpringBootApplication注解和包扫描范围。接着读实体类把数据库表和 Java 对象的映射关系一一对应上。然后读 Mapper 接口和 XML理解每个查询的 SQL 逻辑。再读 Service 层理解业务规则。最后看 Controller 和前端页面把请求链路串起来。这个顺序是从“地基”到“屋顶”的认知路径比随机点开一个文件瞎猜强得多。如果你打算在这个基础上做二次开发建议优先扩展两个方向一是问题标签体系把单一分类升级为多标签关联提高检索的灵活度二是站内消息通知回答或采纳时给用户发送消息提醒让系统的互动闭环更完整。这个题目做到最后你会发现它最大的价值不是那几行代码而是让你完整走了一遍“需求分析 - 数据库设计 - 接口实现 - 部署运行 - 优化迭代”的流程。把这些经历沉淀下来不管是继续做其他项目还是准备面试都会轻松不少。本文还有配套的精品资源点击获取
返回列表