ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

JavaWeb图书管理系统源码解读与IDEA运行配置指南

JavaWeb图书管理系统源码解读与IDEA运行配置指南 简介这是一份基于JavaWeb的图书管理系统完整源码与数据库脚本面向JavaWeb课程设计、毕业设计以及入门学习者。系统采用典型JSPServletJavaBean分层结构包含图书信息管理、借阅归还、读者管理、管理员登录等常用功能模块可帮助读者快速掌握JavaWeb项目从数据库设计到页面交互的完整实现思路。压缩包共595个文件约12.48MB涵盖97个Java源文件、47个JSP页面、90个JS脚本、38个CSS样式以及29个HTML页面和2个SQL数据库脚本另有png/jpg/gif图片素材、XML配置文件与jar包等目录结构清晰便于部署和二次开发。该资源已有570人学习使用适合需要参考完整项目源码、搭建图书管理系统或进行课设毕设实战的开发者。下载后可结合SQL脚本建库再通过IDE导入项目运行快速得到一套可演示的管理系统。1. 基于 JavaWeb 的图书管理系统源码包先搞清楚它值不值得你打开拿到“基于javaweb的图书管理系统源码数据库.zip”时你面对的通常不是一堆零散文件而是一套完整的课设级工程JSP 页面负责展示、Servlet 接收请求、JavaBean 封装数据、DAO 访问 MySQL外加一个 .sql 数据库脚本。这类包在 javaweb 入门和图书管理系统课程设计里非常常见好处是功能够全、链路够短登录、图书信息增删改查、借还书、读者管理全部用最朴素的 Servlet JSP JDBC 实现没有 Spring 帮你隔着一层每一行代码的流转都看得见。适合刚学完 JavaWeb 语法、准备做课程设计的人也适合想找一个 javaweb 项目完整案例 mysql 来复现完整开发流程的人。它的价值不在代码量而在于你能在一小时内把一个项目跑起来再顺着请求链看懂 MVC 是怎么落地的。但先说结论源码和数据库打成 zip 不代表导入就能跑。版本不匹配、Tomcat 没配好、数据库脚本执行顺序错了都会让你在第一步就开始怀疑人生。这篇文章按我自己带课设和帮人远程调项目的顺序把解压后要做的几件事拆开讲清楚。2. 读源码从读懂这两层开始为什么图书管理系统要用三层架构解压之后先别急着双击 index.jsp。这类 javaweb 图书管理系统源码普遍是分层结构JSP 只负责展示Servlet 只负责接收请求和跳转DAO 只负责访问 MySQL。第一次读源码的人容易一头扎进页面标签里我一般会先让人去看 WEB-INF 和配置文件因为请求入口、数据库连接、字符编码这些决定能不能跑起来的东西全在这里。2.1 目录结构页面在外面类在 WEB-INF 里面先摆出一个常见的目录形态不同包的名字会有一点出入但骨架基本一致图书管理系统/ ├── sql/ │ └── books.sql # 数据库初始化脚本建库、建表、示例数据 ├── src/ # 源码目录Maven 工程则是 src/main/java │ ├── com/ │ │ ├── book/dao/ # BookDAO 等数据库访问类 │ │ ├── book/servlet/ # BookServlet 等请求处理类 │ │ ├── book/entity/ # Book、User 等 JavaBean │ │ └── book/util/ # DBUtil 连接工具、编码过滤器 └── webapp/ # Web 根目录IDEA 里也叫 Web 资源目录 ├── index.jsp # 登录页 ├── book/ │ ├── list.jsp # 图书列表 │ ├── add.jsp # 新增表单 │ └── edit.jsp # 编辑表单 ├── css/ js/ images/ # 静态资源 └── WEB-INF/ ├── web.xml # Servlet 映射、欢迎页、过滤器 ├── classes/ # 编译后的 .class 输出 └── lib/ # mysql-connector-java.jar 等第三方包这个结构的核心是所有能通过浏览器直接访问的页面放在 webapp 根下而 WEB-INF 里的东西浏览器无法直接访问只能由 Servlet 转发进去。所以很多项目把 JSP 页面放在 WEB-INF/view 下禁止用户绕过登录页直接敲 URL 访问。如果你看到 list.jsp 放在 book 目录下且没有权限校验这是课设源码的常见偷懒点不是标准做法。读目录时有个技巧先打开 web.xml 看 servlet-mapping就能画出完整的请求路线。比如 BookServlet 映射到 /book意味着打开http://localhost:8080/项目名/book就会进入这个 ServletServlet 查完数据再 forward 到 book/list.jsp。如果你直接访问 book/list.jsp数据永远为空因为没人给页面 setAttribute。2.2 三个核心配置文件web.xml、db.properties、pom.xml先看 web.xml。老式项目靠它做 Servlet 映射新版可以用 WebServlet 注解替代但很多课设包仍然保留了 web.xml里面还会藏一个编码过滤器?xml version1.0 encodingUTF-8? web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee version3.1 !-- 编码过滤器解决 POST 请求和响应乱码 -- filter filter-nameencodingFilter/filter-name filter-classcom.book.util.EncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param /filter filter-mapping filter-nameencodingFilter/filter-name url-pattern/*/url-pattern /filter-mapping !-- Servlet 映射访问 /book 进入 BookServlet -- servlet servlet-nameBookServlet/servlet-name servlet-classcom.book.servlet.BookServlet/servlet-class /servlet servlet-mapping servlet-nameBookServlet/servlet-name url-pattern/book/url-pattern /servlet-mapping welcome-file-list welcome-fileindex.jsp/welcome-file /welcome-file-list /web-app这里的 filter-class 必须和你源码里的实际包名一致。如果源码用了 WebServlet(/book) 注解web.xml 里还保留旧的映射启动时会重复注册报错解决方法是对照源码里的注解把 XML 里的对应 servlet 配置删掉。再看数据库连接配置。这类项目最常用 db.properties 或 jdbc.properties由 DBUtil 加载drivercom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/book_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 usernameroot password123456driver 和 url 是重灾区。MySQL 5.7 时代用com.mysql.jdbc.DriverMySQL 8.0 之后必须改com.mysql.cj.jdbc.Driver同时 url 要带 serverTimezone否则直接报时区错误。password 里的 123456 是课设默认值实际运行前一定要改成你自己的 MySQL 密码。如果 zip 里带 pom.xml说明它是 Maven 工程依赖集中在中央仓库dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version3.1.0/version scopeprovided/scope /dependency注意 servlet-api 必须用 provided因为 Tomcat 自带 servlet 容器实现。如果写成 compile打出的 WAR 里会带上重复的 servlet 类部署时可能出现奇怪的类冲突。2.3 数据库访问层的骨架PreparedStatement 与增删改查的边界图书管理系统的核心操作就是数据库增删改查。DAO 类是离数据库最近的一层也是很多源码包写得最随意的一层。一个合格的 BookDAO 长这样public class BookDAO { public ListBook queryAll() throws SQLException { String sql SELECT id, isbn, name, author, price, stock FROM book ORDER BY id; ListBook books new ArrayList(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql); ResultSet rs ps.executeQuery()) { while (rs.next()) { Book b new Book(); b.setId(rs.getInt(id)); b.setIsbn(rs.getString(isbn)); b.setName(rs.getString(name)); b.setAuthor(rs.getString(author)); b.setPrice(rs.getBigDecimal(price)); b.setStock(rs.getInt(stock)); books.add(b); } } return books; } public int addBook(Book b) throws SQLException { String sql INSERT INTO book(isbn, name, author, price, stock) VALUES(?, ?, ?, ?, ?); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, b.getIsbn()); ps.setString(2, b.getName()); ps.setString(3, b.getAuthor()); ps.setBigDecimal(4, b.getPrice()); ps.setInt(5, b.getStock()); return ps.executeUpdate(); } } }这段代码有几个值得注意的细节。try-with-resources 会自动关闭 Connection、PreparedStatement、ResultSet省掉繁琐的 finally 块。PreparedStatement 的占位符从 1 开始编号不能写成 0。用 setBigDecimal 而不是 setDouble 是为了避免金额出现 0.1 加 0.2 不等于 0.3 的精度问题。数据库增删改查的 update 和 delete 同样走 executeUpdate返回值是受影响的行数业务层可以据此判断操作是否成功。很多源码包在 DAO 里直接用 Statement 拼接字符串比如SELECT * FROM book WHERE name name 这在课设评审里是减分项也埋了 SQL 注入的雷。如果你要二次开发第一步就是把 Statement 全部换成 PreparedStatement顺手把 DBUtil 里的连接获取改成从连接池取性能和可维护性都会上一个台阶。2.4 从浏览器地址到数据库一条完整请求链把这三层串起来看一次图书列表查询是这样流转的浏览器访问/book?actionlist→ Tomcat 根据 web.xml 或注解找到 BookServlet → Servlet 调用 BookDAO.queryAll() → DAO 通过 DBUtil 拿到数据库连接执行 SQL → 查询结果封装成 List 返回 Servlet → Servlet 把 list 塞进 request.setAttribute → forward 到 book/list.jsp → JSP 用 JSTL 或脚本片段遍历输出表格。整条链路里JSP 不知道 SQLDAO 不知道页面长什么样这就是分层的目的。看源码时如果发现某个 Servlet 里直接写了 Connection 且还拼 HTML说明这套代码分层没做干净。这种包能跑但你在上面改需求会很痛苦。拿到之后建议先按上面的链路找出每个页面对应的 Servlet 和 DAO 方法把请求路径抄在一张纸上再动手改业务逻辑。3. 用 IDEA 运行 javaweb 项目配置把源码和数据库一起跑起来很多新手卡在这一步代码看着没问题Tomcat 起不来数据库连不上。这章我按 IDEA 运行 javaweb 项目配置的完整顺序走一遍每一步都是自己踩过之后沉淀下来的最小操作集。3.1 导入前的版本体检JDK、Tomcat、MySQL 三者怎么配对先做版本体检别急着导入。在命令行跑这三个命令java -version # 课设源码大多基于 JDK 8 mysql --version # 5.7 或 8.0 均可驱动会不同 echo $CATALINA_HOME # 检查 Tomcat 环境变量没有也可以手动指定版本配对的常见组合是JDK 8 Tomcat 8.5 MySQL 5.7/8.0或者 JDK 11 Tomcat 9 MySQL 8.0。JDK 17 也能跑 Tomcat 9但项目里如果用了老版本 JSTL可能面临模块化导致的 IllegalAccessError。如果不是很清楚源码依赖最稳妥的是 JDK 8 Tomcat 8.5 组合兼容面最广。Tomcat 下载后不要解压到带中文和空格的路径比如D:\Program Files\apache-tomcat-8.5.100Windows 下中文路径偶尔会引发部署失败或日志乱码。更不要用系统里残留的多个 Tomcat 版本互相混淆一个 IDEA 项目绑定一个 Tomcat 实例端口冲突时会让你怀疑人生。3.2 在 IDEA 里导入工程并配置 Artifact打开 IDEA 后直接选 Open 指向解压目录。如果是普通 Web 工程IDEA 会识别成一个空项目如果是 Maven 工程选 pom.xml 导入。然后按顺序做四件事第一确认 Project SDK。File - Project Structure - Project把 SDK 指到 JDK 8Language Level 设为 8。第二确认 Modules 里有没有把 src 标成 Sourceswebapp 标成 Web 资源目录IDEA 有时候没自动识别需要手动在 Modules 面板右键标记。第三打开 Artifacts 标签点加号选 Web Application: Exploded这是热部署的基础配置千万选 Exploded 而不是 WarWar 每次改代码都要重新打包。第四确认 Output Layout 里已经包含 WEB-INF/classes 和 WEB-INF/lib如果没有右键已编译的模块添加进去。把这个过程用可验证的命令对应起来就是检查编译输出目录# 如果你用命令行构建Maven 工程可以看到 target/classes mvn clean compile ls target/classes/com/book/dao/BookDAO.class # 有 class 说明编译通过IDEA 里走了图形界面本质和这条命令一样编译通过是部署的前提。我见过有人点了半天 Run 按钮最后发现 Modules 里根本没把 src 标为源码根目录所有类都显示红色波浪线编译输出为空Tomcat 一启动就直接 404。3.3 把数据库脚本灌进 MySQL建库、导数据、验证这一步是大多数翻车的根源。拿到 books.sql 后先看它里面有没有 CREATE DATABASE有的话直接灌没有的话先手动建库再指定库导入。我通常用 mysql 客户端命令行比 Navicat 更直观# 创建数据库字符集按脚本要求见不到要求就统一 utf8mb4 mysql -uroot -p -e CREATE DATABASE IF NOT EXISTS book_db DEFAULT CHARACTER SET utf8mb4; # 导入脚本到指定库 mysql -uroot -p --default-character-setutf8mb4 book_db sql/books.sql # 验证导入结果 mysql -uroot -p -e USE book_db; SHOW TABLES; SELECT COUNT(*) FROM book;三个命令的分工是第一个命令负责把库建出来避免脚本里没有建库语句导致后面的表没去处第二个命令用输入重定向把 SQL 文件喂给 MySQL 客户端注意--default-character-setutf8mb4一定要带否则脚本里即使写了CHARACTER SET utf8mb4客户端的连接字符集仍可能把中文搞成乱码第三个命令是冒烟验证看到表清单和图书表行数数据库这步就算过了。Windows 的 PowerShell 里重定向是保留符号直接执行会报错。改用这个替代写法Get-Content sql\books.sql | mysql -uroot -p --default-character-setutf8mb4 book_db也可以直接进入 mysql 客户端后用 source 命令导入这是最不用纠结路径问题的方式mysql -uroot -p book_db source D:/course/book/sql/books.sql;source 的路径用正斜杠或双反斜杠都行注意是 mysql 客户端内部命令不是外部mysql source很多人在这里卡住是因为在 bash 里敲了mysql source xxx。3.4 启动前的端口检查与冒烟验证Tomcat 默认占用 8080 端口MySQL 在 3306。如果之前装过其他服务端口被占会直接启动失败报 Address already in use。先做端口体检# Linux / macOS lsof -i:8080 -i:3306 # Windows PowerShell netstat -ano | findstr :8080 netstat -ano | findstr :3306看到 LISTENING 是正常看到 TIME_WAIT 或者一堆进程占用就不正常。杀掉占用进程后在 IDEA 的 Run Configuration 里把 Tomcat 的 HTTP port 改成 8080 或自定义端口再确认 JMX port 默认是 1099如果也冲突就改成 1098。启动成功后在浏览器输入http://localhost:8080/项目上下文/比如 Deployment 里 Application context 设为/books就访问http://localhost:8080/books/index.jsp看到登录页说明 Servlet 容器正常再输入数据库里存在的账号密码能跳转到主页面整套 javaweb 图书管理系统就算跑通。冒烟验证别只看到登录页就收工。要实际走一遍新增图书、编辑、删除这三个动作因为这些操作会真正触发数据库增删改查能暴露 db.properties 和驱动是否配置正确。很多项目登录页能打开但一提交表单就 500原因往往是数据库连接失败或字符集不对登录环节把这类问题掩盖了。4. 数据库脚本执行的 4 个边界坑从建库到 seed 数据数据库脚本看起来是最不用动脑的部分实际执行时却有一堆边界情况。下面四条都是我反复见过的每一条都比第一眼看起来更坑。4.1 MySQL 5.7 与 8.0驱动、认证插件、时区三连坑现象项目启动时报ClassNotFoundException: com.mysql.jdbc.Driver或者Public Key Retrieval is not allowed甚至是The server time zone value йʱ is unrecognized。原因分三块MySQL 版本、驱动类名、连接参数不匹配。MySQL 8.0 用了新版驱动类名com.mysql.cj.jdbc.Driver老驱动在 8.0 下要么连不上要么认证插件不兼容。同时 8.0 默认的认证插件是 caching_sha2_password老驱动不认识需要 url 里加 allowPublicKeyRetrievaltrue。时区问题则是连接 url 里没指定 serverTimezoneMySQL 返回的空时区或系统时区让驱动无法解析。解决方式是把 db.properties 统一改成兼容 8.0 的写法drivercom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/book_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8allowPublicKeyRetrievaltrue usernameroot password你的密码同时到 webapp/WEB-INF/lib 下确认 mysql-connector-java 的 jar 是 8.x 版本如果是老的 5.1.x去 maven 仓库下 8.0.33 替换掉。如果项目是 Maven 工程直接改 pom.xml 里的版本号再刷新依赖。4.2 字符编码utf8 与 utf8mb4三处对齐现象SQL 导入成功但登录页中文标题变成了问号或者在页面上录入“作者王小明”数据库里存的是???或者 Emoji 直接报错。原因数据库表编码、MySQL 客户端连接编码、JDBC url 编码三处没有对齐。老脚本里常见DEFAULT CHARSETutf8utf8 在 MySQL 里不是完整的 UTF-8存不了 Emoji 和生僻字。而导入命令不带--default-character-setutf8mb4时客户端连接字符集可能是 latin1写进去的东西再正确也会按错误编码解码出来就是问号。解决方式是在建库时就锁死字符集CREATE DATABASE IF NOT EXISTS book_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE book_db; -- 建表统一指定旧表用 ALTER 修正 ALTER TABLE book CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;注意ALTER TABLE ... CONVERT TO会重新编码已有字符串数据如果里面已经是乱码转完之后乱码形态可能保持需要先清掉脏数据再转换。导入命令、JDBC url、web.xml 里的过滤器三者都显式写 UTF-8才能保证从请求到响应一路不乱码。4.3 外键与约束先删表还是先建表现象第一次导入成功第二次再执行同一份 books.sql 报错Table book already exists或者明明先建 book 表导入时却报Cannot add foreign key constraint又或者删表时报Cannot delete or update a parent row: a foreign key constraint fails。原因脚本里建表顺序没考虑外键依赖book 表外键指向 category 表如果先建 book 后建 category外键约束找不到父表直接失败。重复导入时脚本又没做幂等处理已经存在的表和新表的主外键撞在一起。解决方式是在脚本头部加删除和约束控制SET FOREIGN_KEY_CHECKS 0; DROP TABLE IF EXISTS book; DROP TABLE IF EXISTS category; SET FOREIGN_KEY_CHECKS 1; CREATE TABLE category ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE book ( id INT PRIMARY KEY AUTO_INCREMENT, isbn VARCHAR(20), name VARCHAR(100), category_id INT, CONSTRAINT fk_book_category FOREIGN KEY (category_id) REFERENCES category(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;DROP 顺序在没开 FOREIGN_KEY_CHECKS 时必须先删子表 book再删父表 category开了检查则无所谓。重复执行脚本时这段代码保证每次都清空重建避免了叠加错误。很多课设脚本没写这几行你需要在拿到脚本后自己加上。4.4 seed 数据主键冲突与自增值复位现象脚本导入的书有 id 1 到 10int 类型自增主键系统里新增一本书时 id 从 11 开始正常。但如果你手工往表里插过一条 id 为 100 的数据再删掉下次新增就撞主键了或者你再导入一次脚本主键 1 到 10 已存在INSERT 直接报主键冲突。原因MySQL 的 AUTO_INCREMENT 计数器不随 DELETE 回退。INSERT 语句带显式 id 时MySQL 会把当前自增值推进到 max(id)1但如果那个最大 id 的行被删除计数器并不会收回去还可能因为重复导入而错位。解决方式是导入完 seed 数据后显式校正自增值-- 让自增从当前最大 id 的下一位继续 ALTER TABLE book AUTO_INCREMENT 1; -- 如果希望整个表干净重建TRUNCATE 比 DELETE 更彻底 -- 注意有外键关联时要先关闭约束检查 SET FOREIGN_KEY_CHECKS 0; TRUNCATE TABLE book; SET FOREIGN_KEY_CHECKS 1;TRUNCATE会重置自增到 1但它是 DDL 不是 DML执行后无法通过回滚恢复而且外键关联时会拒绝执行所以必须先关闭外键检查。如果只希望清空数据但保留结构并且没有外键依赖DELETE 从业务语义上更安全但自增值仍需用 ALTER 手动复位。5. javaweb 图书管理系统常见问题排查我自己踩过的 5 个坑这一章不按 SQL 或配置分类直接按报错现场讲。每条都是“现象 → 原因 → 解决”的结构你大概率会在某个晚上遇到其中一条。5.1 登录成功后跳转的页面中文全是乱码现象进入登录页时中文正常输入账号密码点登录后首页所有中文变成乱码或者只有表单提交后的内容乱码页面本身正常。原因登录页静态展示走的是 JSP 内容编码但登录表单用 POST 提交后Servlet 没有处理请求体编码request 默认按 ISO-8859-1 解析中文直接变乱码。如果项目里配置了 EncodingFilter最可能是 filter-mapping 的 url-pattern 没写成/*或者过滤器只处理了 response 没处理 request。解决在 Servlet 的第一行也就是任何读取参数之前强制设置请求编码。更好的做法是检查过滤器代码有没有实现request.setCharacterEncoding(encoding)// EncodingFilter 核心逻辑必须在 doFilter 里不止 response request.setCharacterEncoding(UTF-8); response.setCharacterEncoding(UTF-8); response.setContentType(text/html; charsetUTF-8); chain.doFilter(request, response);很多源码包的过滤器只做了 responsePOST 请求参数照样乱。如果你改动代码后还是乱重启 Tomcat 并清浏览器缓存浏览器会缓存旧响应头。5.2 启动成功但访问任何页面都 404现象Tomcat 正常启动控制台没有报错浏览器访问http://localhost:8080/是默认首页访问http://localhost:8080/books/book却 404。原因最常见的不是代码问题而是 IDEA 里 Deployment 的 Application context 没有设置或者设置成了/项目上下文和实际 URL 对不上。另一种情况是源码里的 Servlet 映射是/book但你访问路径写成了/books/book。还有可能是你直接访问了 WEB-INF 下的页面浏览器天然无法直接访问 WEB-INF 内部文件。解决先确认 Run Configuration 里 Deployment 页签的 Application context改成/books然后访问http://localhost:8080/books/book。同时打开源码对照 web.xml 或注解确认 URL 是/book还是/book/结尾大小写也不能错Servlet 映射是区分大小写的。如果项目下没有配置欢迎页面可以直接写全路径http://localhost:8080/books/index.jsp测试。5.3 页面爆 500ClassNotFoundException 或 NoClassDefFoundError现象登录页能打开点击图书列表后报 500控制台堆栈里写着ClassNotFoundException: com.mysql.cj.jdbc.Driver或NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config。原因mysql 驱动 jar 没有进 WEB-INF/lib或者 IDEA 的 Artifact 打包时只打进了 classes 目录lib 里的第三方 jar 没有被当作输出依赖。很多手工导入的非 Maven 工程都会漏这一步。解决检查 Artifact 的 Output Layout确保 WEB-INF/lib 下面能看到 mysql-connector-java.jar。如果没有在 Project Structure - Artifacts - Output Layout 里右键 WEB-INF 目录选 Add Copy of - Module 依赖把 lib 加进去。命令行确认的话# 检查编译输出里有没有驱动 unzip -l target/xxx.war | grep mysql 2/dev/null # 或看 IDEA 的输出目录 find out/artifacts -name mysql-connector* 2/dev/null找不到文件就说明 Artifact 配置漏了重新构建之前记得 Build - Rebuild Project。5.4 数据库连不上时区、端口、密码三重错误现象控制台报Connection refused或者Communications link failure也可能是The server time zone value XXX is unrecognized。原因Connection refused多数是 MySQL 服务根本没启动或者端口不是默认 3306。Communications link failure还可能是驱动类名写错导致根本没正确加载。时区报错是 MySQL 8.0 后常见url 里没加 serverTimezone。密码错则直接报 access denied。解决先用命令行确认数据库服务状态# Linux systemctl status mysql # Windows 服务管理器里找 MySQL 服务或命令行 sc query MySQL80 # 手动测一下能不能连上 mysql -uroot -p -e SELECT 1;能连上再用应用里的账号连确认 db.properties 的 username/password 和 MySQL 实际账号一致。如果 MySQL 不是跑在 localhost还要检查 bind-address 和防火墙。url 里把useSSLfalse加上减少握手失败概率。5.5 改了 JSP 或 Java 代码但页面没变现象在 IDEA 里改了 list.jsp 的表格样式刷新浏览器还是旧页面改了 Servlet 里的查询逻辑重启 Tomcat 后仍是老结果。原因IDEA 默认的 Tomcat 部署方式没有热部署修改 JSP 通常会被更新但修改 class 需要重新编译并重启如果是打 War 包部署War 没重新构建更改根本没有进入部署目录。解决Run Configuration 里把 Deployment 的 artifact 改成 Exploded 模式然后把 On frame deactivation 选成 Update classes and resources这样代码改动后切到浏览器触发 IDEA 自动更新。修改 JSP 后 CtrlShiftF10 手动更新资源修改 Java 类后用 Debug 模式重启线程比重新启动 Tomcat 快很多。JSP 修改不生效时优先看 Tomcat 的工作目录work/Catalina/localhost/项目名下有没有生成新编译的 class没有就是更新逻辑没触发。6. 在源码上做第一个二次开发借阅统计页的架子怎么搭跑通源码只是起点。很多人拿到 javaweb 图书管理系统源码后不知道该从哪改起最容易上手也最有展示价值的改动是加一个统计报表。以“每个分类下有多少本书”为例这个功能能串起 DAO、Servlet、JSP 三层又不会动到核心业务。第一步先写 SQL验证结果再写代码。6.1 加一个统计 DAOLEFT JOIN 保证零记录分类也出现在 BookDAO 里加一个方法public ListMapString, Object countByCategory() throws SQLException { String sql SELECT c.name AS category, COUNT(b.id) AS cnt FROM category c LEFT JOIN book b ON c.id b.category_id GROUP BY c.id, c.name ORDER BY cnt DESC; ListMapString, Object list new ArrayList(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql); ResultSet rs ps.executeQuery()) { while (rs.next()) { MapString, Object row new HashMap(); row.put(category, rs.getString(category)); row.put(cnt, rs.getInt(cnt)); list.add(row); } } return list; }LEFT JOIN 而不是 JOIN 是关键。JOIN 会过滤掉没有图书的分类统计结果少一行看起来像数据丢了。ORDER BY cnt DESC 让数量多的分类排前面页面展示时不用再做排序。然后在 Servlet 里调用这个方法把结果塞到 request 属性里forward 给新页面 statistic.jsp。6.2 先逻辑验证再对接页面写好 DAO 后别急着写页面先用 mysql 客户端把同一句 SQL 跑一遍确认返回的行数符合预期mysql -uroot -p book_db \ -e SELECT c.name AS category, COUNT(b.id) AS cnt FROM category c LEFT JOIN book b ON c.id b.category_id GROUP BY c.id, c.name ORDER BY cnt DESC;返回结果正确再在 JSP 里用 JSTL 遍历 request 里的 list输出成表格。这一步能隔离数据层错误和展示层错误避免页面数据显示不对时你根本说不清是 SQL 错了还是 EL 表达式写错了。我自己以前跳过数据库验证直接写页面结果查出来少一行排查半天发现是 JOIN 把空分类滤掉了浪费了二十分钟。这个教训后来变成了习惯凡是写涉及统计的 SQL先到命令行跑出结果再进代码改起来快得多。希望帮到你。本文还有配套的精品资源点击获取
返回列表