简介:一份基于JavaWeb的云借阅图书管理系统毕业设计源码包,面向计算机专业学生与需要快速搭建可运行项目的开发者。项目采用Spring MVC分层架构,覆盖图书信息管理、借阅流程等核心模块,可直接作为课程设计或毕业设计基础框架。压缩包共169个文件,包含Java源码、JSP页面、Mapper映射XML、CSS/JS前端资源、SQL数据库脚本及依赖JAR包,整体约36.95MB,目录结构清晰,便于导入IDE部署。目前已有795人学习下载。该项目为已通过的高分毕业设计,代码完整无需修改即可运行,从Controller、Service到Mapper的调用链,能帮助理解典型三层架构,配合数据库脚本和前端页面,可较快掌握SpringMVC配置、MyBatis持久化及JavaWeb开发流程,适合毕设参考与实战练习。
1. 拿到这套 javaweb 云借阅图书管理系统源码,先分清它是毕业设计还是生产系统
毕业季最常见的压缩包之一,就是这种《基于javaweb的云借阅图书管理系统源码+数据库(毕业设计).zip》。它用传统 Java Web 技术栈写了一个浏览器访问的图书借阅系统,核心功能是图书录入、读者管理、借书还书和简单的借阅统计。很多第一次拿到源码的同学会误以为“云借阅”是多端同步的云服务,实际上在毕业设计语境里,“云”只代表 B/S 结构,即数据统一存在服务器数据库里,浏览器通过 Servlet 和 JSP 来完成增删改查。这类项目的价值不在架构,而在你能否在三天内让它跑起来、讲清楚每一张表和每一条请求链路,并以此通过答辩。适合人群是急需可运行毕设项目的学生,以及想快速搭一个借阅管理最小后台的初学者。
2. 技术选型与功能拆解:javaweb 项目为什么最适合当毕业设计交付物
2.1 先辨认你拿到的是 Servlet+JSP 还是 SSM 工程
打开压缩包第一件事,别急着解压双击,先看它有没有 pom.xml 或 build.gradle。有 pom.xml 就是 Maven 工程,依赖全在中央仓库,IDEA 会自动下载;如果只有 src 目录和 lib 文件夹、外加一个 .iml 或 .project 文件,那就是传统的 Servlet+JSP+JDBC 工程,jar 包要手动挂到 Artifact 里。“javaweb”这个词在毕业设计里通常指后者,因为很多课程设计还停留在 JSP + Servlet + MyBatis 的手写 dao 阶段。辨认方法很简单:用压缩软件打开包,看最外层目录。常见做法是看有没有 src/main/java 这种 Maven 标准布局,地址上如果出现 com 开头的三级包名,再往下一层看有没有 applicationContext.xml 或 spring-mvc.xml,有就是 SSM。
选型理由:毕业设计选 javaweb 而非 Spring Boot,核心原因是答辩时老师几乎一定会问“请求从浏览器到数据库经历了什么”。Servlet 的生命周期、Filter 的拦截顺序、JDBC 的 Connection 获取,这些在 javaweb 项目里都是写在明面上的代码,而不是被框架自动装配的黑匣子。哪怕答不上来,你至少能对着代码指给老师看。另一个原因是环境轻,JDK + Tomcat + MySQL 就能跑,不像微服务那样要装一堆中间件。对第一次做完整项目的同学来说,这个技术栈的试错成本是最低的。
需要注意的是,这套源码里的 Servlet 版本决定了你的 Tomcat 版本上限。如果它用的是 javax.servlet 包,Tomcat 9 及以下都能跑;如果代码里出现 jakarta.servlet,那就要上 Tomcat 10+,这是近几年升级 JDK 11 之后最容易踩的坑。判断方式就是打开一个 java 源文件看 import 语句,花十秒钟能省下一个下午。
2.2 借阅管理系统的五个核心模块:别把“云”想复杂
功能模块的划分,常见的设计是五块。第一块是管理员登录,负责做 session 校验,未登录直接跳回 login.jsp;第二块是图书管理,对应图书表 book,提供新增、编辑、下架、按书名或 ISBN 模糊查询;第三块是读者管理,对应 reader 表,一般会做读者编号 card_no 的自动生成和手机号校验;第四块是借阅管理,这是整个系统的核心,借书时插入一条 borrow 记录、把 book 表的库存 stock 减一,还书时把这条记录的状态改成“已归还”、把 stock 加一;第五块是统计模块,给管理员一个首页 dashboard,显示总馆藏量、借出量、本月借阅次数。五块业务对应五张表,逻辑上一条直线,这样设计的好处是增删改查边界清楚,写 dao 层和 service 层的时候不会出现“一张表被到处改字段”的混乱。
有些版本还会加一点“云”装饰:把图书封面路径存在数据库里、上传到服务器目录,或者做热门图书轮播图。这些功能在源码里通常就是多一个字段、多一个 JSP 片段,跑通主流程后再加不迟。建议先把借阅主链路走通,再回头补展示层的东西,否则你会在“封面图为什么裂了”这种问题上浪费大量时间。
答辩讲解时,最稳妥的讲述顺序是:管理员登录进入后台 → 先添加分类,再添加图书 → 创建读者 → 给这个读者借两本书 → 演示还书 → 看首页统计数字变化。这正好对应五个模块的调用链路,老师顺着你的操作就能理解整个系统的数据流。记住一句话:毕业设计系统不怕功能少,怕的是功能之间没有关系。借阅模块就是把图书和读者两个孤岛连起来的桥梁。
2.3 源码包里的文件分工:先摸清目录再启动,省掉大半“黑匣子”时间
拿到源码包之后,先建一张自己的“地图”,不用全看懂,但要大概知道什么文件管什么。下面是这套系统常见的目录结构,不同版本略有出入,但大体一致:
| 路径 | 作用 | 坑点 |
|---|---|---|
| src/ 或 src/main/java | Java 源码,按 controller、service、dao、entity、util 分包 | 注意看包名和数据库名是否一致 |
| webapp 或 WebContent | JSP 页面、CSS/JS、图片资源 | 放 JSP 的目录决定访问路径 |
| WEB-INF/web.xml | Servlet 映射、欢迎页、Filter 配置 | 改这里可能造成路径失效 |
| WEB-INF/lib | 第三方 jar 包 | 非 Maven 工程必须手动挂载 |
| sql/ 或 db/ | 建库脚本,cloud_library.sql 之类 | 先看它里面是不是包含建库语句 |
| 说明文档.doc/.md | 环境配置和功能演示说明 | 不要全信,以代码为准 |
拿到包以后,先把 sql 目录里的脚本用文本编辑器打开看一遍。重点看三点:第一,开头有没有 CREATE DATABASE 语句,有的话执行的时候不用手动建库;第二,表名和字段名是什么风格,是 book、reader 这种英文单词还是 t_book、t_reader 这种带前缀,这决定你改连接配置时要不要再改 SQL;第三,有没有初始管理员数据,也就是 INSERT INTO admin 那行,如果没有,你登录页面将无从下手。
常见做法是把源码导入 IDEA 之后再一次性改配置。但更稳的顺序是:先把数据库建好、把连接配置改好,再用 IDEA 打开项目。这能让你在碰到问题时快速判断是代码问题还是环境问题。很多人上来先把项目导进 IDEA,结果一连串报错,根本分不清是数据库没连上还是端口被占用。按“数据库先行、代码后跑”的顺序执行,黑匣子会小很多。
3. 在 IDEA 里把 javaweb 项目跑通:版本对齐、数据库初始化和连接配置
3.1 环境版本:JDK 8、Tomcat 8.5、MySQL 5.7 是这套源码的最稳组合
如果你的机器上还没有装任何环境,我建议按这个版本组合来配:JDK 1.8、Apache Tomcat 8.5.x、MySQL 5.7.x、IDEA 2020 以上版本。这套组合是 javaweb 毕业设计最常用的搭配,原因很简单:JDK 8 是最后一个被几乎所有老项目兼容的版本,很多源码在 JDK 11 下会出现反射或权限报错;Tomcat 8.5 支持 Servlet 3.1,既能跑传统 Servlet 也能跑 Spring MVC;MySQL 5.7 和经典的 mysql-connector-java 5.1.47 驱动配合得很稳,不需要处理 MySQL 8 的加密规则问题。
| 组件 | 推荐版本 | 说明 |
|---|---|---|
| JDK | 1.8(8u201+) | 兼容性最好,编译级别不要超过 1.8 |
| Tomcat | 8.5.x | 支持 Servlet 3.1,Gzip 和编码配置顺手 |
| MySQL | 5.7.x | 与经典驱动配合最稳,索引和字符集坑最少 |
| IDEA | 2020.x 以上 | Artifact 配置界面更直观 |
| mysql-connector-java | 5.1.47 | 与 MySQL 5.7 匹配,注意别混用 8.x 驱动 |
如果电脑上已经装了 MySQL 8,先别急着卸载。常见做法是继续用它,但要把驱动换成 mysql-connector-java 8.0.x,同时把 JDBC 连接 URL 里的参数改一下。具体怎么改,第五章会专门说。毕业生最容易犯的错是把 5.1 的驱动丢到 MySQL 8 上,然后报 Communications link failure,还以为是端口问题。
3.2 导入 IDEA 并配置 Artifact:idea 运行 javaweb 项目配置最常卡住的点
把环境装好之后,导入项目这一步,我建议严格按下面的顺序做,每一步都确认完成再走下一步。
第一步,把 zip 包解压到一个没有中文和空格的路径下,例如 D:\projects\cloud_library。路径里带中文名,Tomcat 的日志输出和资源加载偶尔会因为编码问题抽风,纯英文路径最省心。
第二步,打开 IDEA,File → New → Project from Existing Sources,选中解压出来的目录。如果弹出 “Import Project from external model”,选择 Eclipse 或 Maven 都可以。拿不准的时候选 Eclipse,IDEA 能识别 .classpath 和 .project 文件;没有这些文件就选 “Just import as a normal project”。
第三步,设置 SDK。Ctrl+Shift+Alt+S 打开 Project Structure,Project 选项卡里把 Project SDK 指到 JDK 1.8,Language level 选 8。如果列表里没有 1.8,先到 SDK 里点 Add JDK,把 JDK 安装目录选进去。
第四步,给项目添加 Web 能力。左侧选 Facets,点加号,选 Web。Artifact 这里注意:非 Maven 项目经常不会自动生成 Artifact,你需要点加号选择 Web Application: Exploded,把项目的 webapp 或 WebContent 目录设为 Web Resource Directory。这一步如果做错,后面 Tomcat 启动会直接报 “No artifacts marked”,或者根本不给你启动按钮。
第五步,处理 lib 目录。回到 Project Structure → Libraries,把 WEB-INF/lib 下所有的 jar 包都加进来。这一步很容易被跳过,尤其是刚接触 IDEA 的人,以为 lib 放在那里就能自动加载。非 Maven 项目的 jar 包必须手动挂到 Libraries 里,否则编译时满屏找不到符号。
第六步,配置 Tomcat。打开 Run/Debug Configurations,点加号选 Tomcat Server → Local。在 Deployment 标签页点加号选 Artifact,把上一步建好的 exploded artifact 部署进去;Server 标签页里把 HTTP port 改成 8080,Application context 建议设为 /,这样访问地址就是 http://localhost:8080/,不需要再带项目名。
配置完成以后,点右上角的启动按钮。看到 Tomcat 日志出现 “Server startup” 就代表 web 容器起来了。如果浏览器打开是 404,先回 Application context 那里看一眼,是不是路径前缀没改对,这是最常见的翻车原因。
3.3 初始化数据库:用 mysql 命令行执行 SQL 脚本
数据库的初始化应该在导入 IDEA 之前就做。打开命令行,执行下面这条命令(Windows 上如果没把 mysql 加进 PATH,需要先 cd 到 MySQL 的 bin 目录):
mysql -uroot -p < D:\projects\cloud_library\sql\cloud_library.sql输入 root 密码后回车。如果 SQL 文件第一行就有 CREATE DATABASE,这一步会自动把库建好,你只需要确认没有报错。执行完之后,用下面几条命令检查数据结构是否完整:
mysql -uroot -p show databases; use cloud_library; show tables; select * from admin;这里我建议你把这几条 mysql 常用命令记熟,不只是项目初始化,后面所有“数据库进不去”的问题排查都要靠它们。select * from admin 这条尤其重要,它能告诉你初始管理员账号密码到底存了什么。很多源码的初始密码是明文 admin,也有些版本是 MD5 加密过的一串字符。如果是加密后的值,你又不知道原始密码,最省事的办法是直接执行一条 update 语句把它改成你知道的 MD5 值。
UPDATE admin SET password = MD5('123456') WHERE username = 'admin';这条命令的坑在于,有些版本的密码加盐存储,比如把用户名拼进去再加密,那么 MD5('123456') 跟它原来的算法就对不上。遇到这种情况,找源码里的 MD5Util 或 SHAUtil 工具类,看它加密时有没有拼额外的字符串,按它的逻辑手动生成一条 update 语句。千万不要因为登录不了就重装系统,数据库层的问题九成都是这一条 update 能解决的。
3.4 修改数据库连接参数:db.properties 或 jdbc.properties 一个字符都不能错
数据库建好之后,回到项目源码里找连接配置文件。常见的文件名是 db.properties、jdbc.properties、database.properties,放在 src 根目录或 WEB-INF/classes 下。打开后大概是这个样子:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/cloud_library?useUnicode=true&characterEncoding=utf8&useSSL=false jdbc.username=root jdbc.password=123456参数说明:driver 这行,如果你用的驱动包是 mysql-connector-java 5.1.x,就保持 com.mysql.jdbc.Driver;如果你换成了 8.0.x 驱动,必须改成 com.mysql.cj.jdbc.Driver,否则启动时直接报 ClassNotFoundException。url 里的数据库名 cloud_library 要和 SQL 脚本里建库的名字完全一致,大小写也敏感。useUnicode=true 和 characterEncoding=utf8 是保证存中文不乱码的关键,useSSL=false 是关掉 SSL 警告,不影响功能。username 和 password 就不用说了,填你 MySQL 的实际账号和密码。
改配置文件有个诀窍:永远在 IDEA 里改,不要用记事本。记事本保存的 properties 文件可能是 ANSI 编码,里面如果有中文注释,Tomcat 读到注释时就会报非法字符,然后整个配置加载失败。IDEA 会根据文件头自动按 UTF-8 保存。改完之后,在浏览器地址栏访问登录页,如果看到 500 错误并且控制台里出现 “Access denied for user”,那是用户名密码问题;出现 “Unknown database” 是库名不对;出现 “Communications link failure” 是端口或服务没起来。这三个报错认清楚,数据库连接这一关就彻底拿下了。
4. 数据库设计拆解:五张表如何撑起借阅业务的增删改查和统计
4.1 核心表结构与字段设计:管理员、读者、分类、图书、借阅
虽然不同源码的表名和字段名有区别,但底层设计思路基本一致。下面是这套系统最典型的五张表结构,你可以对照自己拿到的源码看差异:
| 表名 | 核心字段 | 作用 |
|---|---|---|
| admin | id, username, password | 管理员登录凭证 |
| category | id, name, description | 图书分类,如文学、计算机 |
| reader | id, card_no, name, phone, create_time | 读者信息,card_no 是借阅证号 |
| book | id, isbn, name, author, category_id, total, stock | 图书信息,total 是总册数,stock 是当前可借数 |
| borrow | id, book_id, reader_id, borrow_date, return_date, status | 借阅记录,status 区分借出/已还/逾期 |
表之间的关系很直接:book.category_id 关联 category.id,borrow.book_id 关联 book.id,borrow.reader_id 关联 reader.id。字段设计上有几个细节值得你在答辩时主动讲出来。第一,book 表把 total 和 stock 分开存,这是图书管理的标准做法,total 是馆藏总量,stock 是当前还在馆里的数量,借书 stock 减一,还书加一,total 不变。第二,borrow 表的 status 用整数或字符串表示,比如 0 在借、1 已还、2 逾期,不要在表里直接存中文状态,否则写 SQL 统计时条件判断很别扭。第三,大多数版本不会建物理外键,只在逻辑上维护关系,理由是物理外键会拖慢插入速度,而且毕业设计里只要保证 dao 层代码控制好关联就行。
这套设计的巧妙之处在于:借阅模块只需要操作一张 borrow 表,就能同时影响图书库存和读者借阅历史。借书时 INSERT 一条 borrow 记录,再 UPDATE book 表减一册库存;还书时 UPDATE 这条记录的状态和时间,再 UPDATE 库存加一册。两条 SQL 完成三个模块的联动,这就是“事务”在毕业设计里最常见的应用场景。
4.2 借书还书的 SQL 实现:关联查询、库存扣减和延期天数
借书操作的核心代码如下,源码里通常封装在 BorrowDao 的 addBorrow 方法中:
-- 插入一条借阅记录 INSERT INTO borrow (book_id, reader_id, borrow_date, return_date, status) VALUES (12, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL 30 DAY), 0); -- 同时把 book 表库存减一 UPDATE book SET stock = stock - 1 WHERE id = 12 AND stock > 0;逻辑说明:第一条 SQL 插入借阅记录时,借书日期取当前日期,应还日期用 DATE_ADD 在当前日期上加 30 天,status 设为 0 表示在借。第二条 SQL 扣减库存时加了 AND stock > 0 这个条件,防止库存为负。这两个操作必须放在同一个事务里执行,如果只执行第一条而第二条失败,会出现“书借出去了但库存没变”的数据不一致。源码里通常用 Connection.setAutoCommit(false) 开事务,finally 里 commit 或 rollback。
还书操作正好相反:
-- 还书:更新借阅状态 UPDATE borrow SET status = 1, return_date = CURDATE() WHERE id = 21 AND status = 0; -- 库存加回 UPDATE book SET stock = stock + 1 WHERE id = (SELECT book_id FROM borrow WHERE id = 21);这条 UPDATE 的坑在于子查询和更新同一张表可能报错。MySQL 不允许在更新一张表时用子查询引用同一张表的目标行,所以更稳妥的做法是在 Java 代码里先查出 book_id,再执行两条独立的 UPDATE。很多同学翻车就翻在把两步并成一条 SQL,然后被 MySQL 的 “You can't specify target table for update in FROM clause” 劝退。
查询历史借阅记录时,需要把三张表关联起来:
SELECT b.name AS book_name, r.name AS reader_name, br.borrow_date, br.return_date, br.status FROM borrow br JOIN book b ON br.book_id = b.id JOIN reader r ON br.reader_id = r.id WHERE br.reader_id = 3 ORDER BY br.borrow_date DESC;这一条 SQL 是可以直接背下来在答辩时讲的,它展示了 inner join 的用法,也说明你理解表之间的关系。记住,老师不指望你的毕业设计有高并发,只希望你能把自己写的代码讲明白,这条 SQL 就是最好的讲稿。
4.3 用两条统计 SQL 在答辩时讲“系统价值”
统计模块最常被用到的是借阅排行和逾期未还,这两条 SQL 是答辩加分项。借阅排行统计各书被借次数:
-- 图书借阅排行 TOP 5 SELECT b.name, COUNT(br.id) AS borrow_count FROM borrow br JOIN book b ON br.book_id = b.id GROUP BY b.id, b.name ORDER BY borrow_count DESC LIMIT 5;这条 SQL 的关键在于 GROUP BY 和 ORDER BY 的组合。先按图书分组,再用 COUNT 统计每组的借阅记录数,最后按数量倒序取前五。如果你在源码里找不到这个功能,完全可以自己加一个 bookRank.jsp 页面,把这条 SQL 塞进一个新的 dao 方法里,这就是你在毕业设计里体现“改进工作量”的最快路径。
逾期未还名单则是借阅管理的高频需求:
-- 逾期未还读者名单(假设借期 30 天) SELECT r.name, b.name AS book_name, br.borrow_date, DATEDIFF(CURDATE(), br.borrow_date) - 30 AS overdue_days FROM borrow br JOIN reader r ON br.reader_id = r.id JOIN book b ON br.book_id = b.id WHERE br.status = 0 AND DATEDIFF(CURDATE(), br.borrow_date) > 30 ORDER BY overdue_days DESC;这里用到 DATEDIFF 函数计算当前日期与借书日期的差值,再减去 30 天得到逾期天数。写这条 SQL 时要注意:status = 0 的过滤条件必须在前,因为已还的书即使超期了也不算逾期。另外建议把 30 天这个常量提出来,放到代码里做成可配置参数,答辩时就可以说“借期天数可由管理员配置”,这句话的含金量比十页堆砌的截图都高。
5. 避坑指南:javaweb 连接 MySQL 最常见的 5 个翻车现场与排查方法
5.1 现象:IDEA 里 Tomcat 启动按钮置灰,Artifact 无法部署
刚导入项目的时候,右上角的绿色启动按钮是灰色的,点开 Run/Debug Configurations 里也没有 Tomcat Server 选项。原因是 IDEA 没识别到项目的 Web 工程性质,它不知道你要把什么东西部署到 Tomcat。解决方法是回到 Project Structure → Facets,点加号手动添加 Web Facet,在 Configuration 里把 Web Resource Directory 设置为 webapp 或者 WebContent 目录。建好 Facet 后,再到 Artifacts 里添加 Web Application: Exploded,之后去配置 Tomcat 的 Deployment,按钮就不再置灰。这个问题的本质是 IDEA 把导入流程分成了编译和部署两件事,Facet 负责告诉它“这是一个网页项目”,Artifact 负责告诉它“打包什么东西”,两个都配好才能跑。
5.2 现象:MySQL 报 Communications link failure,Tomcat 起不来
日志里出现 Communications link failure,后面跟着连接超时或 UnknownHost,第一反应别去改防火墙,先确认 MySQL 服务是否真的在运行并监听 3306 端口。Windows 上用命令行执行 netstat -ano | findstr 3306,看到 LISTENING 说明服务在跑。如果服务没起来,到服务管理里手动启动 MySQL 服务,并把它设为自动。如果端口在监听还是连不上,那多半是连接 URL 里的端口写错,有人把 3306 写成 3307 或者 8080 都有可能。还有一个容易被忽略的原因:MySQL 8 默认使用 caching_sha2_password 认证,老版本驱动不认识这个协议,表现就是第一次连接时报错或者握手失败。把驱动换到 8.x 并在 URL 里加 serverTimezone=Asia/Shanghai 就行。
5.3 现象:页面中文乱码,图书名和读者姓名全是问号
乱码问题在 javaweb 项目里像传染病一样,一个环节没对齐就全线冒问号。常见原因有三个:JSP 文件本身的编码不是 UTF-8,Tomcat 的 URIEncoding 没设 UTF-8,以及 JDBC URL 里缺少 characterEncoding=utf8。检查顺序从页面往数据库找。打开 JSP 文件看头部有没有 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>,没有就补上。然后检查 Tomcat 的 server.xml,在 Connector 节点上确认加了 URIEncoding="UTF-8"。最后复查 db.properties 里 JDBC URL 带没带 useUnicode=true&characterEncoding=utf8。三个地方都一致了,重启 Tomcat,乱码就不会再出现。如果数据库里之前的乱码数据已经写进去了,不要硬改表结构,执行一条 update 把脏数据重置即可,改表结构反而可能破坏现有数据。
5.4 现象:页面 404 或 Servlet 报 500,路径看起来没问题却始终不通
登录页面能打开,提交表单后 404,或者点击某个链接直接 500。这个问题九成出在 Servlet 的映射路径上。打开 web.xml 或者 @WebServlet 注解,看清楚 urlPatterns 写的是什么,再对照 JSP 里 form 表单的 action 和超链接的 href。前后路径必须精确匹配,多一个斜杠少一个斜杠都会失败。还有一种情况是 @WebServlet 注解和 web.xml 里的映射重复,容器不知道听谁的,直接启动失败或请求异常。解决方法是只保留一种写法,要么全部用注解,要么全部在 web.xml 配。500 报错时,看控制台堆栈是哪个类哪一行抛的异常,最常见的空指针是调用了 queryForList 却拿到 null,检查方法里有没有先做判空。
5.5 现象:Navicat 或 SQLyog 连不上 MySQL 8,root 用户登录失败
数据库工具连不上和项目代码连不上是两回事,但原因经常一样:MySQL 8 的默认加密规则和旧工具不兼容。工具这边可以选用支持 caching_sha2_password 的新版本,或者把 root 用户的加密方式改回 mysql_native_password,一条命令解决:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码'; FLUSH PRIVILEGES;这条命令在 MySQL 命令行里执行,而不是在 Navicat 里执行,因为你现在根本连不上。做完这一步,Navicat 和项目代码都能正常连接。要提醒的是,修改加密规则只影响该用户,不影响数据库里的表和数据,可以放心操作。如果你用的 MySQL 5.7 却遇到连接失败,先查端口和密码是否匹配,别把 8 的解决方法乱套上去。
6. 答辩前把“能跑”变成“能讲”:三处低成本改动让系统更完整
6.1 加一个全局编码过滤器,把乱码问题从源头解决
与其在每一个 Servlet 里写 request.setCharacterEncoding("UTF-8"),不如在 web.xml 里加一个过滤器,请求进来时统一设置编码。这段配置直接抄进 web.xml 的 节点里即可:
<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> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>如果你的工程是纯 Servlet 而没有 Spring 依赖,这段配置会因为找不到 CharacterEncodingFilter 这个类而报错。替代方案是手写一个两三行的 Filter 类,doFilter 里执行 setCharacterEncoding 再 chain.doFilter 放行。写完后你会发现,之前那种“这个页面中文正常、那个页面乱码”的玄学问题全消失了。答辩时老师问过滤器的作用,你就回答:所有请求在进入 Servlet 之前都先过一遍编码设置,保证写入数据库的数据是 UTF-8。这一句话就能展示你对 Servlet 规范的理解。
6.2 把 JDBC 直连换成 Druid 连接池,让启动速度明显变快
源码里每次请求都通过 DriverManager.getConnection 拿数据库连接,这种方式在并发高时性能很差。常见做法是不改动整体代码,只在 dao 层基类里把获取连接的方式换成 Druid 连接池。用 Druid 之前要先下载 druid-1.2.x.jar 放进 lib 目录,然后在 BaseDao 的静态代码块里初始化:
static { ProxyConfig config = new ProxyConfig(); DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/cloud_library?useUnicode=true&characterEncoding=utf8&useSSL=false"); dataSource.setUsername("root"); dataSource.setPassword("123456"); dataSource.setInitialSize(5); dataSource.setMaxActive(20); }逻辑说明:连接池的核心价值是复用连接。初始化时创建 5 个连接放在池子里,请求来了从池子取,用完归还,而不是每次都重新经历“建立连接—认证—断开”的全过程。你不需要在答辩时解释太深的参数,只要能说清 initialSize 是初始连接数、maxActive 是最大连接数,顺便提一句连接用完了要 close,就足够拿分了。改完这个之后,系统首次访问页面的速度明显变快,因为连接已经预热好了。
6.3 预置一组演示数据,准备一条“逾期未还”SQL 当答辩亮点
答辩最容易冷场的瞬间,是老师让你演示“借还书流程最核心的效果”时,系统里只有你自己刚添加的一条数据,页面空空荡荡。我的习惯是在答辩前把演示数据一次性灌进去,提前借出三四本书,其中特意留一条逾期记录,让首页统计图表和排行榜有内容可看。演示的时候,不要只是点按钮,要当着老师的面打开数据库执行一条 SQL,这条就能起到“核弹级”的证明效果:
SELECT r.name AS 读者, b.name AS 书名, DATEDIFF(CURDATE(), br.borrow_date) - 30 AS 逾期天数 FROM borrow br JOIN reader r ON br.reader_id = r.id JOIN book b ON br.book_id = b.id WHERE br.status = 0 AND DATEDIFF(CURDATE(), br.borrow_date) > 30 ORDER BY 逾期天数 DESC;执行完把结果展示给老师,同时说一句:这条 SQL 能帮图书管理员快速找出哪些读者的书逾期未还,这就是系统在实际管理场景中的落地价值。比起口述“我的系统很完整”,这一条 SQL 的说服力强得多。
我当年做课设时最惨的一次,不是代码跑不通,而是答辩前换了一台演示机器,JDK 版本不对导致 Tomcat 起不来,在老师面前手忙脚乱改环境变量改了十分钟。从那以后,我拿到任何源码包第一件事就是把版本要求写成一页 README 放在压缩包里,该记的全记上;答辩用的笔记本一定事先把 Tomcat、MySQL 服务设为开机自启,登录页截图存手机里当紧急后备。希望这篇能帮你在自己的机器上少踩几个同样的坑,顺利把项目跑起来、讲明白。
本文还有配套的精品资源,点击获取