简介:这是一套基于Java技术栈开发的记账系统毕业设计完整资源包,面向Java初学者、高校应届生及希望完整走通Web应用开发流程的读者。项目以MVC设计模式为核心,覆盖Java SE/EE编程、Spring MVC框架、MyBatis或Hibernate持久层、MySQL数据库操作,以及Tomcat等应用服务器的部署运行,知识链条完整。压缩包共280个文件、约71.94MB,其中23个Java源码文件承载业务逻辑,99个XML配置与1个SQL脚本对应框架配置和数据库结构,37个JavaScript与10个CSS文件用于前端交互和样式,3个MP4视频辅助演示项目介绍与部署过程,另有部署文档、命令行脚本及项目配置文件,源码、视频、说明文档、数据库按目录分类存放,结构清晰。目前已有187人学习下载。通过该资源可系统掌握从环境搭建、数据库设计、后端接口开发到前端渲染、最终部署上线的全链路实践方法,说明文档与视频教程相互配合,能有效降低环境配置与数据库连接的学习门槛,既可作为毕业设计参考,也能充当Java Web综合实战训练材料。
1. 基于Java的记账系统毕业设计:一套能跑通的源码包到底值不值得拆
有没有过这种时刻:从学长或网盘里拿到一个“基于Java的记账系统毕业设计”压缩包,解压后面对一屏文件夹和 sql 文件,第一反应不是兴奋而是心虚——这东西到底能不能跑起来?这个标题其实把答案写在名字里了:它交付的不只是源代码,还有数据库脚本、部署文档和部署视频。也就是说,这个方案默认的第一目标是让一个没接触过这套环境的接手人,也能按图索骥把系统从 zip 变成浏览器里的登录页。适合谁?正在做 Java 后端毕设、想省掉从零搭框架时间的学生,以及想借一套完整业务练手、把增删改查和权限验证讲清楚的新手。前提是你别急着改代码,先把环境这关过了。
2. 先把运行环境对齐:JDK版本、MySQL编码、Tomcat端口怎么一次配好
部署一套 Java Web 系统,卡住你的往往不是代码,而是环境和源码预期不一致。同一个 zip 包,在原作者电脑上启动顺畅,到你这里就翻车,绝大多数原因出在 JDK、MySQL、Tomcat 这些基础组件的版本没对齐。这不是玄学,是版本兼容问题。这章教你不动一行业务代码,先把环境对到能启动的状态。
2.1 拿到压缩包先盘三件事:技术栈、构建方式、数据库脚本
打开压缩包后先别急着解压运行。先在目录里找三样东西:pom.xml或build.gradle,src下有没有.java和jsp/static目录,以及后缀为.sql的脚本文件。这三样决定后续每一步怎么做。pom.xml存在说明它是 Maven 管理的 Java Web 项目,依赖下载由 Maven 负责;只有lib目录加一堆 jar 包的,属于传统 Web 项目,要手动把 jar 放进 WEB-INF。这两种项目的启动方式完全不同,搞错会直接卡在第一关。
# 在命令行里逐个确认基础版本,别凭安装时记忆 java -version mvn -v mysql --versionjava -version看 JDK 版本和位数,毕设里最常见的是 JDK 1.8,少数新项目用 11 或 17;mvn -v会额外显示 Maven 当前使用的 JDK 路径,如果它指向的不是java -version那套 JDK,构建时会出现依赖装好但编译失败的情况;mysql --version要同时记下主版本,MySQL 5.7 和 8.0 在认证插件、排序规则、部分 SQL 语法上都有差异,数据库脚本能不能直接跑通,很大程度由它决定。
把版本记下来后,和下面这张表对照就行。
| 组件 | 毕设常见版本 | 检查方式 | 主要坑点 |
|---|---|---|---|
| JDK | 1.8 为主 | java -version | 版本太高导致 JSP 编译失败 |
| MySQL | 5.7 / 8.0 | mysql --version | 8.0 认证插件与旧驱动不兼容 |
| Tomcat | 8 / 9 | startup.bat启动日志 | 端口冲突、编码过滤缺失 |
| Maven | 3.6+ | mvn -v | 本地仓库依赖下载不完整 |
这里多说一句:毕设场景求的是“先能跑、再能懂”,版本不用追最新。如果你发现源码里写的是 Spring Boot + MyBatis 的组合,那部署方式又不同——Spring Boot 内置 Tomcat,mvn package打成 jar 后直接java -jar就能启动,端口默认 8080,根本不需要单独装 Tomcat。看结构再选路线,比盲目装一堆软件高效得多。
2.2 数据库连接参数:一行配置决定你能不能登录
版本看完,真正决定系统能不能连上数据库的是连接配置。常见 SSM 项目里是jdbc.properties,Spring Boot 项目里是application.properties,你要核对的是 URL、用户名和密码这三项。
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/bookkeeping?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true jdbc.username=root jdbc.password=你的密码com.mysql.cj.jdbc.Driver是 MySQL 8 驱动的写法,老项目里常见的com.mysql.jdbc.Driver在 8 里也能用,但会一直打过时警告。URL 里每个参数都别删:useSSL=false关掉 SSL 握手,减少本地调试的报错概率;characterEncoding=utf8强制字符集,和后面的乱码问题直接相关;serverTimezone=Asia/Shanghai解决 MySQL 8 时区报错;allowPublicKeyRetrieval=true解决 MySQL 8 默认认证方式下驱动报Public Key Retrieval is not allowed。
这里有个非常容易白费功夫的操作:一上来就改源码里的密码。正确顺序是先打开命令行,用mysql -u root -p手动登一次,能登上再把密码填进配置。命令行都登不进去,说明问题在 MySQL 安装、服务状态或密码本身,改配置文件没有用,反而会让人在 IDE 里反复重启 Tomcat 浪费时间。
2.3 导入数据库脚本:先建库,再导数据,把字符集钉死
很多初始化脚本里只写了建表语句,没有CREATE DATABASE。如果你直接source,MySQL 会报No database selected,或者把表建进默认库。正确顺序永远是:先建空库,再往库里导数据。
# 第一步:进入 MySQL,创建一个空库 mysql -u root -p CREATE DATABASE bookkeeping DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; EXIT; # 第二步:在命令行导入业务脚本 mysql -u root -p --default-character-set=utf8mb4 bookkeeping < E:/毕设/bookkeeping.sqlDEFAULT CHARACTER SET utf8mb4把库级字符集定死,COLLATE utf8mb4_general_ci是老版本兼容性最好的排序规则,比 MySQL 8 默认的utf8mb4_0900_ai_ci更稳;导入时加--default-character-set=utf8mb4,保证脚本里的中文注释和初始数据不乱码;文件路径不要带中文目录,Windows 命令行在中文路径下经常读不到文件,提示Can't open file。
导入完成后别急着关,先验证三条 SQL:SHOW TABLES;看表是否齐全,SELECT * FROM t_user;看默认账号是否存在,SELECT COUNT(*) FROM t_transaction;看流水表有没有测试数据。如果表存在但没有账号数据,去部署文档里翻默认账号;如果文档也没写,说明这套源码需要自行注册。流水表没有测试数据的记账系统,后面截图和汇报都很吃亏,建议自己补几行真实日期的数据进去。
3. 核心代码线:登录、流水增删改查和统计图表的三段样板写法
环境通了、数据进去了,下一步才是读代码。拿到源代码我最反对一上来就全局搜“TODO”开始改功能。你先要认同它的主业务线:登录鉴权、记账流水增删改查、统计图表。这三段看懂,整个项目你就掌握了。后面不管是改成自己的毕设,还是回答 java 面试里的登录鉴权问题,都从这里展开。
3.1 登录鉴权与密码处理:Session拦截器统一验,别只把按钮藏起来
很多 Web 毕设的“权限控制”只是把登录按钮换成退出链接,绕过登录页直接输 URL 就能进主页,这属于典型的黑匣子式写法。正规一点的做法是:登录接口校验用户名密码,成功后把用户对象放进 Session,再注册一个拦截器对所有受保护路径做统一校验。后端没有这层拦截,前面做再多界面都没意义。
public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getSession().getAttribute("loginUser") == null) { response.sendRedirect(request.getContextPath() + "/login"); return false; } return true; } }preHandle返回false时请求中断,跳回登录页;request.getContextPath()动态取当前项目部署名,避免硬编码路径换环境就失效。登录成功那行代码通常长这样:session.setAttribute("loginUser", user),和这里取loginUser的 key 必须一致。如果是前后端分离,拦截器通常会改成返回 JSON 的 401 状态码,但传统 JSP 项目里直接重定向完全够用。
拦截器要通过 Spring 配置注册,不能只写个类。XML 配置里要同时写清楚拦截哪些路径、放行哪些路径:
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/login"/> <mvc:exclude-mapping path="/register"/> <bean class="com.bookkeeping.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors>/**匹配全部请求,包括 css、js、图片这些静态资源。如果静态资源也被拦截,登录后的页面会样式全丢,看起来像烂了,实际是拦截器没有排除 static 目录。所以通常要把/static/**、/resources/**也加进exclude-mapping。
密码处理是另一个答辩高频点。源码里如果是明文存储,至少改成加盐散列;如果原来只写了 MD5,先保留原算法让登录跑通,再在论文里指出“MD5 撞库成本低,可升级为 BCrypt”。登录校验的代码长这样:
// 验证时先根据用户名取到 salt,再对输入密码加盐散列后比较 String hashed = DigestUtils.md5Hex(password + user.getSalt()); if (hashed.equals(user.getPassword())) { request.getSession().setAttribute("loginUser", user); response.sendRedirect(request.getContextPath() + "/index"); }这里用password + salt再 MD5,同一个密码在不同盐值下结果不同,能挡住一部分彩虹表攻击。你知道这条线就足够把它讲明白了。真正面试聊起来,你还能说“后续计划换成 BCrypt”,这就是从毕设代码延伸到工程意识的加分回答。
3.2 记账流水的增删改查:分页查询是重点,金额字段别用 double
记账系统的核心不是登录,是流水表增删改查。记一笔、查列表、改金额、删记录。我见过不少源码把列表一次性查出来,再让前端做分页,这种代码数据量一涨就卡。常见可靠的做法是后端分页,MySQL 里用LIMIT完成。
<select id="selectPageByUserId" resultType="com.bookkeeping.entity.Transaction"> SELECT id, user_id, category_id, amount, type, remark, create_time FROM t_transaction WHERE user_id = #{userId} ORDER BY create_time DESC LIMIT #{offset}, #{pageSize} </select>ORDER BY create_time DESC保证新账显示在列表第一行;LIMIT #{offset}, #{pageSize}表示从offset开始取pageSize条。Java 里计算规则是offset = (pageNum - 1) * pageSize,pageNum从 1 开始,这是分页最容易算错的地方。代码层的对照也很关键:
public PageResult<Transaction> pageQuery(int userId, int pageNum, int pageSize) { int offset = (pageNum - 1) * pageSize; List<Transaction> list = transactionMapper.selectPageByUserId(userId, offset, pageSize); long total = transactionMapper.countByUserId(userId); return new PageResult<>(list, total, pageNum, pageSize); }total必须单独count一次,前端表格才知道总记录数和总页数。不要为了省一次查询用SQL_CALC_FOUND_ROWS把 count 和 list 拼在一起,数据量大时反而更难调优。返回结果里带上total、pageNum、pageSize,正好对应前端分页组件的三个参数,改起来也不用动页面。
增删改查里最容易被忽略的是删除。直接DELETE FROM t_transaction WHERE id = #{id}看着简单,但账单删掉后统计也会跟着变,答辩时老师一定会问“删错了能恢复吗”。我的建议是:如果源码是物理删除,保留它,但在论文里写明“生产环境可改成逻辑删除”,也就是给表加deleted字段,查询统一过滤deleted = 0。这句话不用实现,能说出来就说明你想过数据安全。
3.3 统计图表的数据来源:让SQL把账算好,别在Java里循环求和
记账系统的统计页一般有饼图和柱状图。新手容易把列表全查出来,然后在 Java 里用switch按分类累加金额,这种写法数据量一大就慢,而且代码全是循环,答辩时讲不清楚。常见做法是让 MySQL 聚合层直接返回算好的结果:
SELECT c.name AS categoryName, SUM(t.amount) AS totalAmount FROM t_transaction t JOIN t_category c ON t.category_id = c.id WHERE t.user_id = #{userId} AND t.type = #{type} AND t.create_time >= #{startTime} AND t.create_time < #{endTime} GROUP BY c.id, c.name ORDER BY totalAmount DESC;JOIN 把分类名称带出来,避免在 Java 里再查一遍分类表;type参数决定统计收入还是支出;时间范围用>=和<组成半开区间,不会把endTime当天数据重复统计进去。GROUP BY后面同时写c.id和c.name,是 MySQLonly_full_group_by模式下的硬性要求:select 里的非聚合列必须完整出现在 group by 里,只写c.id在部分版本会直接报错。
还有一条很实用的经验:写统计功能不要先写 Java 再编 SQL。先在命令行里用真实数据把 SQL 调出正确结果,再搬进 Mapper。SQL 能算的绝不放进 Java 循环,这是数据库设计的基础意识。后面第 6 章给折线图的按天统计,也是同一个思路,只是把GROUP BY换成日期函数。
4. 数据库设计:E-R关系、decimal精度、索引与外键怎么取舍
代码读懂了,论文里最厚的一章就是数据库设计。这块要能对答如流:为什么表要拆,金额为什么不用 double,外键到底建不建,索引是怎么加速查询的。数据库设计不是写给文档看的,它直接决定增删改查好不好写、统计查得快不快。
4.1 记账系统最少需要几张表:四张表把业务说圆
记账业务至少覆盖四个概念:谁在记(用户)、记到哪(账户)、怎么归类(分类)、每笔账本身(流水)。对应下来就是用户表、账户表、分类表、流水表。有的简单毕设把账户表去掉,只留三张表也能跑,但老师问“怎么记录支付方式”就会卡住。要么加账户表,要么在流水表里放一个支付方式字段。
| 表名 | 职责 | 关键字段 | 关系 |
|---|---|---|---|
| t_user | 用户 | 用户名、密码、状态 | 被流水和分类引用 |
| t_account | 账户/钱包 | 用户id、账户名、余额 | 被流水引用 |
| t_category | 收支分类 | 用户id、分类名、类型 | 一对多到流水 |
| t_transaction | 流水 | 用户id、分类id、金额、类型、时间 | 核心业务表 |
这四张表画 E-R 图时正好是常规的一对多关系:用户对分类是一对多,分类对流水的多对一,流水对账户也是多对一。把关系理清,建表语句才不会乱。很多代码里的 bug 不是逻辑错,而是表关系没想清楚就开始写 Mapper,写到 JOIN 才发现字段对不上。
4.2 建表SQL的关键参数:金额用DECIMAL,外键别滥用
表结构设计直接影响代码复杂度。下面这套是记账系统比较典型的基础。写的时候把注释也带上,因为部署文档里通常不会单独解释字段含义,而答辩老师会逐字段问。
-- 用户表 CREATE TABLE t_user ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(32) NOT NULL UNIQUE, password VARCHAR(64) NOT NULL COMMENT '存散列值,不要存明文', salt VARCHAR(16) DEFAULT NULL, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, status TINYINT DEFAULT 1 COMMENT '1正常 0禁用' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; -- 收支分类表 CREATE TABLE t_category ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, name VARCHAR(32) NOT NULL, type TINYINT NOT NULL COMMENT '1收入 2支出', sort INT DEFAULT 0, KEY idx_category_user (user_id), CONSTRAINT fk_category_user FOREIGN KEY (user_id) REFERENCES t_user(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='收支分类表'; -- 流水表 CREATE TABLE t_transaction ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, category_id INT NOT NULL, account_id INT DEFAULT NULL, type TINYINT NOT NULL COMMENT '1收入 2支出', amount DECIMAL(12,2) NOT NULL COMMENT '金额统一用decimal', remark VARCHAR(255) DEFAULT NULL, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY idx_user_time (user_id, create_time), CONSTRAINT fk_transaction_user FOREIGN KEY (user_id) REFERENCES t_user(id), CONSTRAINT fk_transaction_category FOREIGN KEY (category_id) REFERENCES t_category(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流水表';DECIMAL(12,2)表示整数部分 10 位、小数 2 位,个人记账到百亿级别都够用。金额绝对不能用FLOAT或DOUBLE,因为二进制浮点数在比较和累加时会出现0.1 + 0.2 != 0.3的精度问题,账单金额必须精确到分,这是数据库增删改查里最容易翻车的隐藏雷。
user_id上建普通索引KEY idx_category_user,因为分类统计会反复按 user 过滤;流水表上的KEY idx_user_time (user_id, create_time)是联合索引,配合第 3 章的分页查询WHERE user_id = ? ORDER BY create_time DESC,能走索引直接排序,不需要 filesort。外键约束在毕设里保留完全没问题,能体现关系完整性;但你在论文里要能说出另一面:生产环境的流水类表通常去掉外键,因为高并发写入时外键校验会拖慢速度并放大锁范围。
create_time用DATETIME而不是TIMESTAMP。TIMESTAMP上限 2038 年,还受时区影响;DATETIME没有这些限制,配合DEFAULT CURRENT_TIMESTAMP能让系统自动记录发生时间,代码里少写一行赋值逻辑。
4.3 数据库脚本管理与结构修改:给未来留后悔药
做毕设中途,你很可能想给流水表加一个“支付方式”字段。这时候最忌讳直接在数据库客户端里改完就完事。因为 zip 包里的初始化脚本还停在你改之前,换到答辩机器上重新导库,表结构对不上直接翻车。常见做法是保持初始化脚本不动,把结构升级写成独立增量脚本。
-- v2_alter_transaction_add_pay_method.sql ALTER TABLE t_transaction ADD COLUMN pay_method TINYINT DEFAULT 1 COMMENT '1现金 2微信 3支付宝' AFTER remark;AFTER remark控制字段在表中的显示位置,不影响逻辑;TINYINT表达几种支付方式足够。增量脚本的好处是能重复执行、保留改动痕迹,写论文时把脚本变更记录贴进数据库设计章节,比空口讲“我改了表结构”更有说服力。如果你不想引入额外工具,也有更简单的备份方法:改结构前把整表导出来,相当于一份后悔药。
mysqldump -u root -p bookkeeping t_transaction > backup_transaction.sqlmysqldump导出的文件自带DROP TABLE IF EXISTS和CREATE TABLE,恢复时会把结构和数据一起还原。想在演示现场做删数据、改金额这类操作,有这个备份在就不会慌。开发阶段的数据库脚本管理养成这个习惯,比任何第三方工具都管用——脚本变更记录越完整,出问题的概率越低。
5. 部署避坑手册:五个最容易让毕设翻车的现场
这章写给遇事别硬猜的人。所有部署问题都有日志:Tomcat 日志、MySQL 报错、控制台 stack trace,至少有一个在说话。遇到问题先把现象抄下来,再对下面五条。很多问题看着复杂,实际原因就一行。
5.1 SQL导入报错:先怀疑编码,再怀疑MySQL版本语法
现象:用客户端导入.sql文件,报错含Unknown collation: 'utf8mb4_0900_ai_ci',或者执行到某行提示You have an error in your SQL syntax,也可能表建了一部分,但中文数据全变成问号。
原因:MySQL 8.0 导出的脚本默认带utf8mb4_0900_ai_ci排序规则,5.7 不识别;或者脚本里夹了视图、存储过程和特殊注释字符;再就是客户端连接字符集不是 utf8mb4。
解决:把建库语句里的排序规则改成utf8mb4_general_ci再建库。如果脚本内容不允许自由改动,用命令行指定字符集导入:
mysql -u root -p --default-character-set=utf8mb4 bookkeeping < init.sql这里有一条血泪经验:SQL 导入报错时,不要一行行手改脚本。先看脚本开头的SET NAMES语句,如果有SET NAMES utf8mb4,先执行它;如果没有,统一走命令行参数指定字符集。改脚本只改一处,治标不治本。
5.2 Tomcat端口被占用:启动失败先看日志,别急着换端口
现象:双击startup.bat弹窗一闪而过;或者在 IDE 里启动 Tomcat,控制台最后一行写着Address already in use: JVM_Bind 8080。
原因:上一个 Tomcat 进程没关干净,或者有其他开发工具占用了 8080、8005 端口。大多数时候不是代码问题,你的项目还没跑起来就被端口挡住了。
解决:先查端口占用,再杀进程。
netstat -ano | findstr 8080 taskkill /PID 2764 /Fnetstat -ano | findstr 8080会列出占用 8080 的进程 PID;taskkill /PID后面填真实 PID,/F表示强制结束。如果你舍不得杀进程,也可以改 Tomcat 的server.xml把端口换掉,但换完所有访问 URL、截图里的地址都要跟着变,文档和汇报全对不上。我的习惯是杀进程而不是换端口。
5.3 登录成功反而跳404:context-path没对齐
现象:登录页能开、账号密码也正确,但登录成功后跳转的地址显示 404,而且地址里的项目名不是你部署时的项目名。
原因:代码里的跳转语句硬编码了项目名,比如sendRedirect("/bookkeeping/index"),而本机部署名是BookkeepingSystem;或者 IDE 的 Deployment 配置改了 context path,但代码里没跟着改。
解决:跳转路径统一用request.getContextPath()动态拼接:
response.sendRedirect(request.getContextPath() + "/index");getContextPath()会自动返回当前实际部署名,比如/bookkeeping,拼上/index正好是完整地址。硬编码项目名是黑匣子式写法,换一台机器、换一个部署名就翻车。排查方法很简单:看 404 页面的地址栏,把项目名那段对一下server.xml里的 Context 配置。
5.4 中文乱码:从页面到MySQL每一环都要UTF-8
现象:首页能打开,但页面显示用户名变成ç™»å½,或者数据库表里的中文全是????。有时候输入中文存进去再看是好的,刷新一次就乱了。
原因:JSP 页面、HTTP 响应、JDBC 连接、MySQL 表这四层字符集,只要有一层不是 UTF-8 就会乱。最常见的是漏了 JDBC URL 里的characterEncoding=utf8,或者数据库客户端在导入数据时用了默认的 gbk 字符集。
解决:从请求入口统一编码。在web.xml里加一个 Spring 提供的编码过滤器:
<filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter>forceEncoding=true会强制 request 和 response 都使用 UTF-8,避免只处理请求不处理响应。JSP 页面顶部再确认存在<%@ page contentType="text/html;charset=UTF-8" %>,加上第 2 章里 JDBC URL 和建库语句的 utf8mb4,四层对齐乱码自然消失。排查顺序是:先看页面源码里的编码声明,再看浏览器地址栏参数,最后看数据库字段的字符集属性,逐层排除,不要乱试方法。
提示:字符集问题改完一定要重启 Tomcat,只刷新页面不生效,因为过滤器在容器启动时就注入了。
5.5 部署视频与本机环境不一致:视频只看流程,不看逐帧
现象:视频里双击startup.bat就启动成功,你双击闪退;视频里 MySQL 回车就能登录,你的 mysql 要密码;视频里导入 sql 一次成功,你导入报错。
原因:部署视频的作者在自己机器上录的,系统版本、软件路径、账号密码都和你的环境有差异。视频能证明的是“这套 zip 有标准流程”,不代表你的机器参数必须和视频里逐字一样。
解决:以部署文档为主,以视频为辅。视频重点看三步——数据库怎么导入、项目怎么放进 Tomcat、IDE 里怎么等依赖下载完;其他操作跟着文档做。日志比视频诚实,Tomcat 启动日志第一行就写着它加载的是哪个 JDK、哪个项目路径,对着日志排查比暂停视频放大看清每个字高效得多。
6. 给毕设加一个能讲清楚的加分点:收支趋势接口与验证动线
如果原项目只有分类饼图,可以加一个近 30 天收支趋势图。工作量小、能讲,而且面试官一听就懂:它就是按天分组合计收入支出,数据让 SQL 一次算完。
SELECT DATE_FORMAT(create_time, '%m-%d') AS day, SUM(CASE WHEN type = 1 THEN amount ELSE 0 END) AS income, SUM(CASE WHEN type = 2 THEN amount ELSE 0 END) AS expense FROM t_transaction WHERE user_id = #{userId} AND create_time >= DATE_SUB(CURDATE(), INTERVAL 29 DAY) GROUP BY DATE_FORMAT(create_time, '%m-%d') ORDER BY day;CURDATE()是今天,往前推 29 天、加上今天正好 30 天;DATE_FORMAT(create_time, '%m-%d')把时间转成MM-dd的字符串,方便前端直接当 x 轴;CASE WHEN type = 1 THEN amount ELSE 0 END让收入支出各自成列。后端只返回有数据的那几天,空日期由前端图表补零,职责更清楚。这个接口加完,前面第 3 章的聚合 SQL 思路就串成了一条线。
演示动线也要提前彩排。这里有一份可以直接用的验证清单。
| 验证步骤 | 操作 | 预期结果 |
|---|---|---|
| 1 数据库恢复 | 用初始化脚本重建空库并导入 | 四张表出现,流水表有测试数据 |
| 2 登录 | 使用部署文档里的默认账号 | 登录成功并跳转首页 |
| 3 记一笔 | 金额 200.50,备注“午餐” | 列表第一条出现该记录 |
| 4 修改 | 金额改成 180.00 | 列表与统计数值同步变化 |
| 5 删除 | 删除刚才这笔 | 统计图数据对应回落 |
| 6 归属感处理 | 改页面标题、包名、页脚信息 | 全局搜索旧项目名无残留 |
步骤 6 常被忽略。毕设源码里经常带原作者姓名、学校名、包名,交付前逐处改掉,这在源代码管理上也是一次干净的重命名。演示前恢复一次干净的数据库,别带着之前测试的脏数据上场,否则老师看到异常数字会影响印象分。
注意:演示当天只走主流程,不要现场加新功能。能稳定跑通的系统比能演示新特性的系统更让老师放心。
我自己处理每个外来源码包的习惯是:先完整跑通再重构,跑通前绝不改业务逻辑;改代码只挑三处——登录、分页、统计,三处都看懂就敢说“这是我维护过的系统”。这个习惯帮我躲过了很多次临时改崩的坑,也让我在演示现场敢当场记一笔、改一笔给老师看。希望帮到你。
本文还有配套的精品资源,点击获取