微信小程序+Java后端考研题库毕业设计:从建表到联调全链路实战
简介这是一套面向高校计算机相关专业学生的毕业设计/课程设计完整项目包主题为考研知识题库微信小程序采用微信小程序前端与Java后端分离架构适合正在准备毕业设计、需要项目实战经验或想学习小程序全栈开发的同学参考。压缩包共1243个文件约14.57MB涵盖wxml、wxss、js等小程序页面与逻辑文件vue、scss等后台管理前端资源以及java后端源码、sql数据库脚本、json配置、png与svg图片素材和说明文档前后端与数据库结构完整。目前已有216人学习下载可作为同类选题的参考方案。项目包含可运行的源码、数据库脚本与配套说明读者可据此梳理小程序端页面跳转、题库展示与答题交互理解Java后端的接口设计与数据表关系并借助bat脚本与配置文件快速完成环境搭建与部署调试对撰写论文与答辩演示均有实际帮助。1. 考研题库小程序加 Java 后端一套毕业设计到底要打通哪些环节考研知识题库类小程序看着就是“刷题 看解析”真动手才知道它同时踩在三条线上微信小程序的页面与登录态、Java 后端的接口与数据、以及题库本身的结构化组织。很多同学选题时觉得简单做完发现最难的不是写 CRUD而是题目分类、错题记录、收藏状态和用户进度这几张表怎么设计以及小程序端怎么在弱网下把体验兜住。这套「微信小程序 Java 后端」的组合适合计算机相关专业做毕业设计也适合想练一个前后端分离项目实战的人。它不需要复杂算法但能把登录鉴权、分页查询、关联查询、状态同步这些工程基本功走一遍。下面按我实际搭过的顺序把选型、建表、接口、联调和踩坑讲清楚你照着能跑起来也能判断这个方向值不值得投入。2. 技术选型与题库数据模型先把表设计对后面少返工2.1 为什么后端选 Spring Boot 而不是 Servlet 手写毕业设计里常见两种后端写法一种是纯 Servlet JDBC另一种是 Spring Boot MyBatis。前者能体现“我懂底层”但接口一多参数解析、JSON 序列化、跨域、事务都要自己写时间全耗在重复代码上。Spring Boot 的价值在于把 Web 层、数据层、配置管理收敛成约定你只需要关注业务。对考研题库这种“接口数量中等、逻辑不复杂、但要稳定联调”的场景Spring Boot 是更稳的选择。我一般会这样分层Controller 只做参数校验和返回封装Service 写业务规则比如同一用户同一题只能有一条错题记录Mapper 负责 SQL。这样后面加“每日一练”“模拟考试”时不用动已有接口。依赖上最小集合是 spring-boot-starter-web、mybatis-spring-boot-starter、mysql-connector-java再加一个 JWT 工具做登录态。版本不用追新选你本地 JDK 能稳定跑的即可JDK 8 或 11 都行。!-- pom.xml 关键依赖其余按需裁剪 -- dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version2.3.1/version /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt-api/artifactId version0.11.5/version /dependency /dependencies这段依赖里web 提供内嵌 Tomcat 和 JacksonMyBatis 负责 SQL 映射jjwt 用来签发和校验 token。注意 MyBatis 的版本要和 Spring Boot 版本匹配否则启动时报NoClassDefFoundError多半是版本错位。数据库连接写在application.yml账号密码用环境变量注入别硬编码进仓库。2.2 题库核心表怎么拆题目、选项、分类、用户行为题库类项目最容易翻车的地方是表设计。有人把选项直接塞进题目表的一个字段里用逗号分隔结果做“选项乱序”“统计每个选项被选次数”时全得改。正确做法是拆成四张核心表question题干、解析、分类、难度、question_option选项内容、是否正确、排序、category科目/章节、user_question_record用户答题记录、对错、时间。错题本和收藏不单独建表用记录表里的状态字段区分减少关联。CREATE TABLE question ( id BIGINT PRIMARY KEY AUTO_INCREMENT, category_id BIGINT NOT NULL, content TEXT NOT NULL, analysis TEXT, difficulty TINYINT DEFAULT 1, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE question_option ( id BIGINT PRIMARY KEY AUTO_INCREMENT, question_id BIGINT NOT NULL, option_label CHAR(1) NOT NULL, option_text VARCHAR(500) NOT NULL, is_correct TINYINT DEFAULT 0, sort_no INT DEFAULT 0, INDEX idx_question (question_id) ); CREATE TABLE user_question_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL, question_id BIGINT NOT NULL, user_answer CHAR(1), is_correct TINYINT, is_favorite TINYINT DEFAULT 0, answer_time DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_user_question (user_id, question_id) );user_question_record上的唯一索引是关键它保证同一用户对同一题只有一条记录答错后重做就更新这条而不是无限插入。is_favorite和is_correct分开存收藏和错题互不影响。分类表用 parent_id 做自关联支持“科目 → 章节 → 知识点”三级前端拿树形结构渲染筛选。这里有个参数要注意option_label用 CHAR(1) 存 A/B/C/D比存整型更直观导出数据时不用再映射。2.3 小程序端页面结构四个 tab 就够用小程序端不要一上来堆十几个页面。考研刷题的核心路径是选分类 → 答题 → 看解析 → 回顾错题。对应四个 tab首页分类入口 每日推荐、刷题答题卡片、错题本、我的收藏、进度、设置。答题页用swiper或手动维护 index 切换题目选项用radio-group实现单选。这里有个细节小程序单选框在选中态和禁用态样式差异大建议自定义样式别直接用原生外观否则 iOS 和安卓表现不一致。数据请求统一封装一个request.js在里面注入 token、处理 401 跳登录、统一错误提示。不要把wx.request散落在每个页面否则改接口域名时你会想哭。登录用wx.login拿 code 换 openid后端生成 JWT 返回前端存 storage后续请求带在 header 里。这套流程是标准做法网上例子多但要注意 code 只能用一次且有时效别缓存。3. 后端接口与小程序联调从登录到答题的完整链路3.1 登录鉴权接口code 换 token 的完整实现登录是整条链路的起点也是最容易出问题的地方。小程序调wx.login拿到临时 code传给后端后端拿 code appid secret 去微信接口换 openid 和 session_key。这里注意appid 和 secret 必须放后端绝不能写在小程序代码里否则被人抓包就泄露了。换到 openid 后查用户表没有就注册有就更新登录时间然后签发 JWT 返回。PostMapping(/login) public Result login(RequestBody LoginDTO dto) { // 1. 用 code 换 openid这里省略 HTTP 调用细节 String openid wechatService.getOpenid(dto.getCode()); // 2. 查用户不存在则注册 User user userService.findByOpenid(openid); if (user null) { user userService.register(openid); } // 3. 签发 token有效期 7 天 String token jwtUtil.sign(user.getId(), 7); return Result.ok(new LoginVO(token, user.getNickname())); }Result是统一返回封装包含 code、msg、data 三个字段前端根据 code 判断成功失败。JWT 的 payload 里只放 userId别放敏感信息因为它是可解码的。有效期设 7 天是折中太短用户老要重登太长泄露风险大。前端拿到 token 后存wx.setStorageSync请求拦截器里读出来放 header。如果接口返回 401清 storage 并跳登录页。3.2 题目列表与答题提交分页、乱序与判分题目列表接口要支持按分类筛选、分页、随机抽题。分页用LIMIT offset, size但要注意深分页性能数据量大时用游标。随机抽题用ORDER BY RAND()在几万条以内还能接受再大就要预生成随机序列。答题提交接口接收 questionId 和 userAnswer后端查正确答案判分写入或更新user_question_record返回是否正确和解析。PostMapping(/answer) public Result submitAnswer(RequestBody AnswerDTO dto, RequestAttribute Long userId) { // 1. 查题目和正确选项 Question question questionService.getById(dto.getQuestionId()); String correct optionService.getCorrectLabel(dto.getQuestionId()); // 2. 判分 boolean isCorrect correct.equals(dto.getUserAnswer()); // 3. 写入记录唯一索引保证更新而非重复插入 recordService.saveOrUpdate(userId, dto.getQuestionId(), dto.getUserAnswer(), isCorrect); return Result.ok(new AnswerVO(isCorrect, question.getAnalysis())); }判分逻辑看着简单但要注意大小写和空格。用户答案传上来先trim().toUpperCase()否则 a 和 A 会被判错。saveOrUpdate用INSERT ... ON DUPLICATE KEY UPDATE实现依赖前面建的唯一索引。返回解析时如果用户答错可以只返回正确答案和解析答对则返回简短提示避免直接给解析导致“刷题变看题”。3.3 错题本与收藏状态同步的两种做法错题本和收藏的状态同步有两种做法一种是每次进入页面都请求后端拿最新列表简单但流量大另一种是本地缓存 增量同步体验好但逻辑复杂。毕业设计建议用第一种把分页做好就行。错题本接口查is_correct 0的记录关联题目表拿题干收藏查is_favorite 1。取消收藏就是更新字段不是删除记录这样答题历史还在。-- 错题本分页查询 SELECT q.id, q.content, r.user_answer, r.answer_time FROM user_question_record r JOIN question q ON q.id r.question_id WHERE r.user_id #{userId} AND r.is_correct 0 ORDER BY r.answer_time DESC LIMIT #{offset}, #{size};这个查询走uk_user_question索引的前缀 user_id再过滤 is_correct数据量大时建议加(user_id, is_correct)联合索引。注意别在循环里查题目详情那是 N1 问题用 JOIN 一次拿完。前端渲染时错题本要显示“你的答案”和“正确答案”对比这需要后端把正确选项也带出来别让前端再发一次请求。4. 联调避坑那些让你加班到凌晨的细节4.1 跨域与域名校验本地开发先关校验现象小程序开发者工具里请求后端报“不在以下 request 合法域名列表中”。原因小程序默认只允许 https 且已备案域名。解决开发阶段在开发者工具“详情 → 本地设置”勾选“不校验合法域名”后端本地跑 http 即可。上线前必须换 https 并在小程序后台配置域名。另外后端要开 CORS否则浏览器调试接口时被拦。4.2 登录态失效token 过期没提示现象用户刷着题突然所有接口 401页面空白。原因token 过期后前端没统一处理各页面各自报错。解决在 request 封装里统一拦截 401清 storage弹提示并跳登录页。同时后端 JWT 校验失败要返回 401 而不是 500否则前端判断不了。这个坑我踩过用户反馈“用着用着就白屏”查了半天是 token 过期。4.3 题目选项乱序后判分错乱现象前端把选项打乱显示用户选 A后端按原始顺序判分结果判错。原因选项乱序只在前端做后端不知道映射关系。解决要么后端返回时就乱序并带上原始 label要么前端提交时传原始 label 而不是显示位置。我一般让后端在返回题目时就把选项顺序打乱同时每个选项带自己的 label前端提交 label这样判分不会错。4.4 数据库连接池耗尽现象压测或多人同时用时接口报“无法获取连接”。原因连接池配置太小或连接没释放。解决Spring Boot 默认 HikariCPmaximum-pool-size设 10 到 20 够毕业设计用关键是 Service 方法别开事务后做远程调用否则连接被长时间占用。检查代码里有没有手动Connection没 close 的地方用 MyBatis 一般不会但混用 JDBC 时要小心。4.5 小程序端 setData 频繁导致卡顿现象答题页切换题目时卡顿选项点击延迟。原因每次setData传整个大对象渲染层通信开销大。解决只 setData 变化的最小字段比如只更新当前题 index 和选项选中态不要把整个题目列表重新 set。另外图片资源别放太大题干里的公式图压缩后再用。5. 进阶技巧把题库做成能持续用的工具5.1 用本地缓存做离线刷题小程序有wx.setStorageSync单 key 上限 1MB总上限 10MB。可以把用户最近刷的 50 道题和错题缓存到本地弱网时先读缓存联网后再同步。实现上答题提交先写本地队列网络恢复后批量提交。注意缓存要带版本号题目更新后旧缓存要失效。这个技巧能让答辩演示时不怕断网体验分拉满。5.2 答题进度与统计接口“我的”页面要显示刷题总数、正确率、今日刷题数。这些统计别每次实时算用一张user_stat表答题时更新计数。正确率 正确数 / 总数注意除零。今日刷题数按日期分组查或者用 Redis 的日 key 计数。毕业设计用 MySQL 的DATE(answer_time)分组就够数据量不大。-- 用户统计更新答题后调用 INSERT INTO user_stat (user_id, total_count, correct_count, update_date) VALUES (#{userId}, 1, #{isCorrect}, CURDATE()) ON DUPLICATE KEY UPDATE total_count total_count 1, correct_count correct_count #{isCorrect}, update_date CURDATE();isCorrect传 0 或 1直接加到 correct_count 上省去判断。update_date用来判断是否跨天跨天时今日计数要重置。这个表用 user_id 做主键保证一人一条。5.3 题库导入从 Excel 到数据库的批量脚本题库不可能一条条手录用 Excel 整理后写个导入脚本。格式建议题干、选项 A-D、正确答案、解析、分类、难度。用 Python 的 openpyxl 读 Excel拼成 SQL 或直接调后端批量接口。注意文本里的单引号和换行要转义否则 SQL 报错。批量插入用INSERT INTO ... VALUES (...), (...)一次几百条比逐条快得多。# 简化的 Excel 导入逻辑 import openpyxl wb openpyxl.load_workbook(questions.xlsx) ws wb.active rows [] for row in ws.iter_rows(min_row2, values_onlyTrue): content, a, b, c, d, correct, analysis, category row # 转义单引号避免 SQL 注入和语法错误 content content.replace(, ) rows.append(f({content}, {a}, {b}, {c}, {d}, {correct}, {analysis}, {category})) sql INSERT INTO question_temp (content, a, b, c, d, correct, analysis, category_id) VALUES ,.join(rows) print(sql)这个脚本输出 SQL再手动执行或写到文件。更稳的做法是调后端接口让后端做校验和事务。导入后要抽查选项数量是否都是 4 个、正确答案是否在选项范围内、分类 id 是否存在。我一般会写个校验 SQL把异常数据捞出来人工修。5.4 答辩演示的稳妥习惯答辩现场网络不可控我一般会提前做三件事一是本地起后端数据库用本地 MySQL不依赖云服务二是小程序开发者工具勾选不校验域名用本地 IP 请求三是准备一份离线数据万一登录接口挂了用固定 token 走演示流程。这些准备花不了多少时间但能避免现场翻车。另外代码里别留System.out.println调试输出答辩老师看到会觉得不专业用日志框架统一输出。这套方案我从建表到联调走下来最深的体会是题库项目的难点不在技术深度而在数据一致性和状态同步。把唯一索引、事务边界、前端缓存这三件事想清楚后面加功能就是体力活。如果你正在选毕业设计题目这个方向值得做因为它能让你把前后端分离的完整链路走一遍面试时也有东西讲。希望帮到你。本文还有配套的精品资源点击获取