MZH 图书馆管理系统
MZH Library Management 是一个基于 Java 11、Maven WAR、JSP、Servlet、JDBC DAO 和 MySQL 的 B/S 图书馆管理系统。项目以 Tomcat 部署为目标,采用传统 Java Web 分层结构,适合用于课程设计、Java Web 实训、图书馆业务原型验证,以及学习 Servlet -> Service -> DAO -> MySQL 的完整数据流。
当前仓库已经包含登录认证、角色权限、馆藏检索、图书管理、分类管理、读者档案、借阅流通、读者借阅历史、报表中心、管理员用户管理和系统日志查看等功能切片。
核心功能
- 登录与会话管理:通过
/login登录,认证成功后进入/dashboard;会话中只保存安全的AuthenticatedUser快照、角色代码和权限代码集合。 - 角色工作台:管理员、馆员、读者分别通过
/admin/home、/librarian/home、/reader/home进入对应区域。 - 馆藏检索:通过
/catalog按图书编号、书名、作者和分类检索图书。 - 图书管理:通过
/books维护图书信息,支持新增、编辑、删除和库存状态管理。 - 图书分类管理:通过
/book-categories维护图书分类,并防止删除仍被图书引用的分类。 - 读者管理:通过
/readers维护读者档案、联系方式、状态和最大借阅数量。 - 借阅流通:通过
/borrowing完成借书、还书、续借、逾期筛选和库存联动更新。 - 读者借阅历史:读者通过
/reader/loans查看自己的借阅记录。 - 报表中心:通过
/reports查看馆藏汇总、借阅汇总、逾期列表和热门图书排行。 - 用户管理:管理员通过
/admin/users维护管理员、馆员和读者登录账户。 - 系统日志:管理员通过
/admin/system-logs查询关键操作、审计和异常日志。
技术栈
| 类别 | 当前配置 |
|---|---|
| Java | Java 11,maven.compiler.release=11 |
| 构建工具 | Maven,WAR 项目 |
| Web 技术 | Servlet 4.0、JSP、JSTL |
| Servlet API | javax.servlet:javax.servlet-api:4.0.1,provided |
| JSP 标签库 | javax.servlet:jstl:1.2 |
| 数据库 | MySQL,JDBC DAO 访问 |
| MySQL 驱动 | com.mysql:mysql-connector-j:8.0.33,runtime |
| 部署产物 | target/library-management.war |
| Web 配置 | src/main/webapp/WEB-INF/web.xml,web-app 版本 4.0 |
| 编码 | Maven 源码编码 UTF-8;Web 请求通过 CharacterEncodingFilter 使用 UTF-8 |
建议使用兼容 Servlet 4.0 的 Tomcat 9.x 运行该 WAR。数据库脚本使用 InnoDB、utf8mb4 字符集和检查约束,建议使用 MySQL 8.x。
项目结构
.
├── pom.xml
├── README.md
├── src
│ ├── main
│ │ ├── java/com/mzh/library
│ │ │ ├── controller/ Servlet 控制器,负责路由、参数读取和 JSP 转发/重定向
│ │ │ ├── dao/ DAO 接口
│ │ │ ├── dao/impl/ JDBC DAO 实现
│ │ │ ├── entity/ JavaBean、枚举、查询条件和报表对象
│ │ │ ├── exception/ DAO 异常
│ │ │ ├── filter/ 编码、登录认证、权限过滤器
│ │ │ ├── service/ Service 接口、权限策略和通用结果对象
│ │ │ ├── service/impl/ 业务服务实现
│ │ │ └── util/ JDBC、密码哈希、Session 常量等工具
│ │ ├── resources
│ │ │ ├── db/schema.sql
│ │ │ └── db.properties.example
│ │ └── webapp
│ │ ├── WEB-INF/web.xml
│ │ ├── WEB-INF/jsp/ 受保护的 JSP 页面和 JSP 片段
│ │ ├── static/css/app.css
│ │ ├── static/images/library-login.svg
│ │ └── index.jsp
│ └── test/java/com/mzh/library/service
│ └── *Check.java 服务层和权限策略自检类
└── target/ Maven 构建输出,已被 .gitignore 忽略
本地数据库配置文件 src/main/resources/db.properties 也已被 .gitignore 忽略。不要提交真实数据库地址、账号或密码。
分层设计
项目遵循以下边界:
JSP/CSS 页面 -> Servlet 控制器 -> Service 业务层 -> DAO 数据访问层 -> MySQL
- JSP 只负责展示、表单和用户交互,不直接访问数据库,不编写业务流程。
- Servlet 负责读取请求参数、做基础格式校验、调用 Service,并决定转发 JSP 或重定向。
- Service 负责权限检查、业务规则、事务边界和跨 DAO 工作流,例如借书、还书、续借和库存更新。
- DAO 负责 SQL、JDBC 资源访问和 MySQL CRUD,不返回 HTML 或 Servlet 对象。
- 过滤器统一处理 UTF-8 编码、登录拦截和基于权限的访问控制。
数据库初始化
数据库脚本位于:
src/main/resources/db/schema.sql
脚本会创建并使用数据库 mzh_library,包含以下核心表:
roles:角色定义。permissions:权限定义。role_permissions:角色与权限的关联。users:登录账户,密码字段保存 PBKDF2 哈希。system_logs:系统操作、审计和异常日志。readers:读者档案、联系方式、状态和借阅上限。book_categories:图书分类。books:图书基础信息、分类、总册数、可借册数和状态。borrow_records:借阅、归还、续借和逾期判断所需记录。
初始化示例:
mysql -u root -p < src/main/resources/db/schema.sql
脚本内包含本地验证用的演示角色、权限、用户、读者、分类和图书数据。演示账户只用于本地脚手架验证;在非本地数据库中使用前应更换或删除这些数据。本文档不提供任何登录明文密码。
本地配置
复制配置模板:
cp src/main/resources/db.properties.example src/main/resources/db.properties
模板内容使用以下键:
db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/mzh_library?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
db.username=library_user
db.password=change_me
按本机 MySQL 环境调整 db.url、db.username 和 db.password。实际配置文件不应提交到版本库。
如果你希望单独创建应用数据库用户,可以在 MySQL 中按需授权,例如:
CREATE USER 'library_user'@'localhost' IDENTIFIED BY '<your-local-password>';
GRANT ALL PRIVILEGES ON mzh_library.* TO 'library_user'@'localhost';
FLUSH PRIVILEGES;
请将示例中的占位密码替换为本地安全密码,不要把真实密码写入 README、提交记录或共享截图。
构建与部署
在项目根目录执行:
mvn clean package
如果当前 shell 找不到 mvn,本工作区规范记录的 Maven 路径为:
/home/sjy/.sdkman/candidates/maven/current/bin/mvn clean package
构建成功后会生成:
target/library-management.war
部署到 Tomcat 的常见方式:
- 确认 MySQL 已启动,
mzh_library已初始化。 - 确认
src/main/resources/db.properties已写入本地数据库连接信息。 - 执行 Maven 打包。
- 将
target/library-management.war放入 Tomcat 的webapps/目录,或通过 Tomcat Manager 上传。 - 启动或重启 Tomcat。
- 默认情况下,WAR 文件名会形成访问上下文
/library-management,实际路径以 Tomcat 配置为准。
示例访问地址:
http://localhost:8080/library-management/login
主要路由
以下路由来自 src/main/webapp/WEB-INF/web.xml、welcome-file 配置和对应 Servlet:
| 路由 | 处理者 | 用途 |
|---|---|---|
/(welcome-file: index.jsp) |
index.jsp |
欢迎入口,页面会重定向到 /login |
/login |
LoginServlet |
登录页和登录提交 |
/logout |
LogoutServlet |
退出登录 |
/dashboard |
DashboardServlet |
登录后的总览页 |
/admin/home |
RoleAreaServlet |
管理员区域首页 |
/librarian/home |
RoleAreaServlet |
馆员工作台 |
/reader/home |
RoleAreaServlet |
读者中心 |
/catalog |
BookCatalogServlet |
馆藏检索 |
/books、/books/new、/books/edit、/books/update、/books/delete |
BookManagementServlet |
图书管理 |
/book-categories、/book-categories/new、/book-categories/edit、/book-categories/update、/book-categories/delete |
BookManagementServlet |
图书分类管理 |
/readers、/readers/new、/readers/edit、/readers/update、/readers/delete |
ReaderManagementServlet |
读者档案管理 |
/borrowing、/borrowing/new、/borrowing/create、/borrowing/return、/borrowing/renew |
BorrowingManagementServlet |
借阅、归还、续借 |
/reader/loans |
ReaderLoanHistoryServlet |
当前读者借阅历史 |
/reports |
ReportServlet |
报表中心 |
/admin/users、/admin/users/new、/admin/users/edit、/admin/users/update、/admin/users/deactivate |
UserManagementServlet |
管理员用户管理 |
/admin/system-logs |
SystemLogServlet |
系统日志查询 |
/unauthorized |
UnauthorizedServlet |
无权限提示 |
静态资源路径 /static/ 不要求登录。除 /、/login、/unauthorized、/favicon.ico 和静态资源外,其他页面会经过 AuthenticationFilter 和 AuthorizationFilter。
角色与权限
系统当前包含三类角色。运行时权限由 PermissionPolicy 根据 Role 枚举授予;schema.sql 同时保留 roles、permissions、role_permissions 表和本地种子数据,但当前登录流程不会从 role_permissions 动态加载权限。
| 角色代码 | 显示名称 | 权限概览 |
|---|---|---|
administrator |
管理员 | 运行时策略授予全部 Permission 枚举权限;具体入口仍受路由规则约束 |
librarian |
馆员 | 可管理图书、读者、借阅流通,查看报表和馆藏 |
reader |
读者 | 可查看馆藏,并访问读者自己的借阅历史 |
权限代码包括:
manage_usersmanage_booksmanage_readersmanage_borrowingview_reportsview_system_logsview_catalogborrow_books
访问控制重点:
/admin/system-logs需要view_system_logs。/admin/**用户管理入口需要manage_users。/books/**和/book-categories/**需要manage_books。/readers/**需要manage_readers。/borrowing/**需要manage_borrowing。/reports需要view_reports。/catalog需要view_catalog。/reader/loans需要borrow_books,并且必须是reader角色。
当前代码中的读者自助入口是 /reader/loans 借阅历史查看;借书、还书和续借操作由管理员或馆员通过 /borrowing 工作台处理。
业务规则摘要
- 图书以
book_identifier作为面向用户的唯一编号。 - 图书分类名称唯一,已被图书引用的分类不能直接删除。
- 图书状态使用
available、unavailable、archived。 - 读者以
reader_identifier作为面向用户的唯一编号。 - 读者状态使用
active、suspended、inactive,最大借阅数量范围为 1 到 50。 - 借阅记录状态使用
active、returned;逾期不是单独状态,而是由未归还且due_at早于当前时间的记录推导。 - 借书会在同一事务中创建借阅记录并减少图书可借册数。
- 还书会在同一事务中标记归还并恢复可借册数。
- 续借会延长应还时间并增加续借次数,当前 MVP 对单笔借阅限制一次续借。
- 用户管理变更会写入系统日志,审计信息不应记录密码、明文凭据或密码哈希。
开发约定
- 保持 Servlet -> Service -> DAO -> MySQL 的层次边界。
- JSP 页面只渲染 Servlet 设置的 request/session 属性,避免 JSP scriptlet、SQL、JDBC 或业务流程。
- 受保护操作必须经过服务层权限校验,不能只依赖页面按钮是否显示。
- 新增数据库访问时使用参数化 SQL 或 PreparedStatement 风格,避免拼接用户输入。
- 多表一致性操作放在服务层事务边界中,DAO 只处理具体 SQL。
- 用户可见的页面文案、表单标签、按钮、空状态和服务反馈消息使用简体中文。
- URL、请求参数名、Java 标识符、数据库枚举值和权限代码保持现有代码形式。
- 本地私密配置只放在
src/main/resources/db.properties,不要提交真实凭据。
测试与检查
当前仓库在 src/test/java/com/mzh/library/service/ 下包含多个自检类:
AuthServiceCheckBookServiceCheckBorrowingServiceCheckPermissionPolicyCheckReaderServiceCheckReportServiceCheckSystemLogServiceCheckUserAccountServiceCheck
这些自检类使用 public static void main 和内部断言。当前 pom.xml 没有引入 JUnit/TestNG,也没有配置 Surefire 执行 *Check,因此 mvn test 会编译测试源码,但不会自动运行这些自检类。
常用编译和打包检查命令:
mvn test
mvn clean package
如需手动运行自检类,可在 mvn test 编译完成后执行:
for check in AuthServiceCheck BookServiceCheck BorrowingServiceCheck PermissionPolicyCheck ReaderServiceCheck ReportServiceCheck SystemLogServiceCheck UserAccountServiceCheck; do
java -cp target/classes:target/test-classes "com.mzh.library.service.${check}"
done
如果 Maven 不在 PATH 中,可使用:
/home/sjy/.sdkman/candidates/maven/current/bin/mvn test
/home/sjy/.sdkman/candidates/maven/current/bin/mvn clean package
文档或页面调整后的人工自查建议:
- README 中的路径、路由和依赖版本是否与
pom.xml、web.xml、schema.sql一致。 - 是否意外写入真实数据库账号、密码、连接串或生产部署信息。
- JSP 中是否出现 SQL、JDBC、密码字段展示或业务逻辑 scriptlet。
- 管理入口是否仍与
AuthorizationFilter的权限规则一致。
常见问题
访问页面时跳回登录页
除 /、/login、/unauthorized、/favicon.ico 和 /static/ 外,系统默认要求登录。请确认已经登录,并检查 Tomcat 会话是否过期。当前登录会话超时时间为 30 分钟。
登录或数据库操作提示服务不可用
优先检查:
- MySQL 是否启动。
mzh_library是否已经通过schema.sql初始化。src/main/resources/db.properties是否存在。db.url、db.username、db.password是否与本地 MySQL 一致。- MySQL Connector/J 依赖是否已被 Maven 正确下载。
打包后访问路径不是 /library-management
Maven 当前将 WAR 产物命名为 library-management.war。Tomcat 通常会用 WAR 文件名作为上下文路径,但如果你在 Tomcat 中手动配置了 Context,最终访问路径以 Tomcat 配置为准。
可以把 db.properties 提交吗?
不可以。src/main/resources/db.properties 是本地私密配置,已经被 .gitignore 忽略。只应提交 src/main/resources/db.properties.example。
README 为什么不列出演示账号密码?
数据库脚本包含本地验证用演示数据,但项目要求 README 不写入未经确认的默认登录明文密码,也不扩散任何凭据。需要本地调试时,请由维护者按当前数据库脚本和安全要求单独确认或重置账号。
维护提示
当 pom.xml、web.xml、数据库表结构、角色权限、主要 JSP 路径或测试入口变化时,应同步更新本 README,避免部署步骤和功能说明与实际代码脱节。