基于Thymeleaf+Servlet的图书管理系统开发实战
1. 项目概述这个基于ThymeleafMavenServletMySQL的图书管理系统框架是我在实际开发中总结的一套完整解决方案。它采用了Java Web开发中最经典的架构组合特别适合中小型图书管理系统的快速开发。我在多个实际项目中验证过这套框架的稳定性和扩展性今天就来详细拆解它的技术实现。2. 技术栈选型解析2.1 为什么选择ThymeleafThymeleaf作为现代Java模板引擎相比JSP有显著优势自然模板特性直接在浏览器打开就能预览无需启动服务器强大的表达式语言支持复杂的页面逻辑处理与Spring生态完美集成虽然我们这里用Servlet但Thymeleaf依然表现出色实际开发中我常用这些Thymeleaf特性!-- 数据绑定示例 -- div th:text${book.title}/div !-- 循环处理 -- tr th:eachbook : ${books} td th:text${book.id}/td /tr !-- 条件判断 -- span th:if${book.stock} 0 th:text库存${book.stock}/span2.2 Maven的依赖管理Maven的pom.xml配置是项目基石。关键配置要点dependencies !-- Servlet API -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency !-- Thymeleaf核心 -- dependency groupIdorg.thymeleaf/groupId artifactIdthymeleaf/artifactId version3.0.12.RELEASE/version /dependency !-- MySQL驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.25/version /dependency /dependencies注意MySQL 8.x版本驱动类名已改为com.mysql.cj.jdbc.Driver与5.x的com.mysql.jdbc.Driver不同2.3 Servlet的核心作用在这个框架中Servlet承担着控制器(Controller)的角色。我通常采用一个前端控制器模式WebServlet(/*) public class DispatcherServlet extends HttpServlet { private TemplateEngine templateEngine; Override public void init() { // 初始化Thymeleaf模板引擎 ServletContextTemplateResolver resolver new ServletContextTemplateResolver(getServletContext()); resolver.setPrefix(/WEB-INF/templates/); resolver.setSuffix(.html); templateEngine new TemplateEngine(); templateEngine.setTemplateResolver(resolver); } protected void doGet(HttpServletRequest request, HttpServletResponse response) { String path request.getRequestURI().substring(request.getContextPath().length()); switch(path) { case /books: showBookList(request, response); break; // 其他路由处理... } } }3. 数据库设计与实现3.1 MySQL表结构设计图书系统的核心表结构设计CREATE TABLE books ( id int(11) NOT NULL AUTO_INCREMENT, isbn varchar(20) NOT NULL, title varchar(100) NOT NULL, author varchar(50) NOT NULL, publisher varchar(50) DEFAULT NULL, publish_date date DEFAULT NULL, price decimal(10,2) DEFAULT NULL, stock int(11) DEFAULT 0, category_id int(11) DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY isbn_unique (isbn) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE categories ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(50) NOT NULL, description varchar(200) DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;3.2 DAO层实现我推荐采用JDBC连接池的方式public class BookDAO { private DataSource dataSource; public BookDAO() { // 使用HikariCP连接池 HikariConfig config new HikariConfig(); config.setJdbcUrl(jdbc:mysql://localhost:3306/library); config.setUsername(root); config.setPassword(password); dataSource new HikariDataSource(config); } public ListBook findAll() throws SQLException { String sql SELECT * FROM books; try (Connection conn dataSource.getConnection(); PreparedStatement stmt conn.prepareStatement(sql)) { ResultSet rs stmt.executeQuery(); ListBook books new ArrayList(); while (rs.next()) { Book book new Book(); book.setId(rs.getInt(id)); book.setTitle(rs.getString(title)); // 其他字段... books.add(book); } return books; } } }4. 前后端交互实现4.1 控制器到视图的数据传递Servlet中处理请求并渲染视图的典型流程protected void showBookList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { ListBook books bookDAO.findAll(); request.setAttribute(books, books); WebContext ctx new WebContext(request, response, getServletContext(), request.getLocale()); ctx.setVariable(books, books); templateEngine.process(book/list, ctx, response.getWriter()); } catch (SQLException e) { throw new ServletException(Database error, e); } }4.2 Thymeleaf页面展示对应的Thymeleaf模板示例!DOCTYPE html html xmlns:thhttp://www.thymeleaf.org head title图书列表/title /head body h1图书库存/h1 table thead tr thID/th th书名/th th作者/th th价格/th th库存/th /tr /thead tbody tr th:eachbook : ${books} td th:text${book.id}/td td th:text${book.title}/td td th:text${book.author}/td td th:text${#numbers.formatDecimal(book.price, 1, 2)}/td td th:text${book.stock}/td /tr /tbody /table /body /html提示Thymeleaf的#numbers.formatDecimal可以方便地格式化数字显示第一个参数是小数位数第二个是整数部分最小位数5. 项目部署与优化5.1 Maven打包配置war包打包配置示例build finalNamelibrary/finalName plugins plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-war-plugin/artifactId version3.3.2/version /plugin /plugins /build使用命令打包mvn clean package5.2 性能优化建议模板缓存生产环境开启Thymeleaf缓存resolver.setCacheable(true); templateEngine.setCacheManager(new StandardCacheManager());连接池配置合理设置连接池参数config.setMaximumPoolSize(20); config.setMinimumIdle(5); config.setConnectionTimeout(30000);静态资源处理配置默认Servlet处理静态资源servlet-mapping servlet-namedefault/servlet-name url-pattern/static/*/url-pattern /servlet-mapping6. 常见问题解决方案6.1 MySQL连接问题问题现象Communications link failure解决方案检查MySQL服务是否启动确认连接URL格式正确MySQL 8.x需要时区参数jdbc:mysql://localhost:3306/library?useSSLfalseserverTimezoneAsia/Shanghai检查用户名密码是否正确6.2 Thymeleaf模板解析错误问题现象TemplateResolutionException: Template could not be resolved排查步骤确认模板文件放在/WEB-INF/templates/目录下检查模板文件后缀是否与配置一致确认ServletContext路径正确6.3 Maven依赖冲突问题现象NoSuchMethodError 或 ClassNotFoundException解决方案使用mvn dependency:tree查看依赖树排除冲突依赖dependency groupIdgroup/groupId artifactIdartifact/artifactId exclusions exclusion groupIdconflict-group/groupId artifactIdconflict-artifact/artifactId /exclusion /exclusions /dependency7. 扩展与进阶7.1 添加分页功能实现思路DAO层添加分页参数public ListBook findPage(int page, int size) { String sql SELECT * FROM books LIMIT ?, ?; // 使用(preparedStatement.setInt(1, (page-1)*size)等) }控制器计算分页信息int total bookDAO.count(); int totalPages (int) Math.ceil((double)total / size); request.setAttribute(currentPage, page); request.setAttribute(totalPages, totalPages);页面添加分页导航div classpagination a th:href{/books(page${currentPage}-1)} th:unless${currentPage} 1上一页/a span th:eachi : ${#numbers.sequence(1, totalPages)} a th:href{/books(page${i})} th:text${i} th:classappend${i currentPage} ? active/a /span a th:href{/books(page${currentPage}1)} th:unless${currentPage} totalPages下一页/a /div7.2 文件上传功能Servlet 3.0的文件上传实现表单设置form th:action{/upload} methodpost enctypemultipart/form-data input typefile namefile button typesubmit上传/button /formServlet处理MultipartConfig WebServlet(/upload) public class UploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) { Part filePart request.getPart(file); String fileName Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); try (InputStream fileContent filePart.getInputStream()) { // 保存文件到服务器 Files.copy(fileContent, Paths.get(/uploads, fileName)); } } }这套框架经过多次项目实战检验在中小型图书管理系统开发中表现稳定可靠。特别是在快速开发原型系统时这种轻量级架构能大大缩短开发周期。我在实际使用中发现合理组织项目结构后后续功能扩展也非常方便。

相关新闻

BepInEx模组框架零基础实战指南:3步让Unity游戏用上插件

BepInEx模组框架零基础实战指南:3步让Unity游戏用上插件

BepInEx模组框架零基础实战指南:3步让Unity游戏用上插件 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx 看到别人游戏里多出神秘新功能、全新UI,自己却只会…

2026/10/17 19:03:13 阅读更多 →
掌握Python开发的五个关键阶段,帮你少走弯路

掌握Python开发的五个关键阶段,帮你少走弯路

夜深人静,你对着屏幕上跳动的报错信息,第三次怀疑自己是不是选错了路。Python号称“最简单的编程语言”,但简单只是它的表象,真正让你困在原地的,从来不是语法,而是那种“我好像会了,又好像什么…

2026/10/8 19:52:24 阅读更多 →
后端接口性能优化,我优先排查这五个地方

后端接口性能优化,我优先排查这五个地方

数据库的慢查询日志往往最能说明问题。如果你发现某个接口的耗时与数据量成正比,或者随着业务增长越来越慢,第一步就该去看它执行的SQL。我见过很多接口优化案例,最终都归结为一条走了全表扫描的SQL。用EXPLAIN查看执行计划时,重点…

2026/10/18 3:10:55 阅读更多 →

最新新闻

React Native三区列表布局:跨端一致性实践

React Native三区列表布局:跨端一致性实践

做跨平台应用做久了,因为目标平台里多了鸿蒙,列表布局的选择就自然往“一套代码,三端保持观感一致”的方向收敛。最近做合同模块重构,我把合同记录列表改成了最稳的经典三区结构:左边放合同封面缩略图,中间…

2026/10/19 13:15:47 阅读更多 →
PostgreSQL恢复监控实战:SQL洞察WAL回放与主备延迟

PostgreSQL恢复监控实战:SQL洞察WAL回放与主备延迟

如果你管过 PostgreSQL 的主从架构,大概率经历过这种时刻:备库恢复突然变慢、主备延迟飙高、或者备库干脆卡住不动,而日志里只剩下一条孤零零的 restartpoint complete 。真正让人头疼的是——你没法从日志里看清"现在到底恢复到哪里了…

2026/10/19 13:15:47 阅读更多 →
代码评审流于形式?open-code-review实践:从流程设计到自动化质量门禁落地

代码评审流于形式?open-code-review实践:从流程设计到自动化质量门禁落地

代码评审这件事,说的人多,做到位的人少。我见过太多团队把Review当成发布流程里的一道签字手续,PR挂了两天没人看,临上线前被催着点个Approve,真正的问题全留给测试和用户去发现。做这套open-code-review实践&#xff…

2026/10/19 13:15:47 阅读更多 →
JSP逆向思维实战:从注册功能拆解Web请求链路与设计边界

JSP逆向思维实战:从注册功能拆解Web请求链路与设计边界

1. 从"注册"这个动作说起:为什么逆向思维值得聊做Web开发的人对注册功能再熟悉不过了。一个表单,几个输入框,提交按钮,后端写库,完事。但如果你把视角倒过来——不是站在"我要实现注册功能"的角度…

2026/10/19 13:15:47 阅读更多 →
计算机网络交换技术精讲:电路交换、报文交换与分组交换对比

计算机网络交换技术精讲:电路交换、报文交换与分组交换对比

计算机网络第一章的内容,很多同学是跳着看的,觉得什么“三网融合”“因特网组成”都是背一背就完事。但第一章第二节的交换技术,我建议你拿出至少两小时精读,因为后面学到的路由器、IP、传输层、时延计算,全都在这里埋…

2026/10/19 13:15:47 阅读更多 →
两参数威布尔分布风速建模:MATLAB参数估计与拟合优度检验实战

两参数威布尔分布风速建模:MATLAB参数估计与拟合优度检验实战

简介:这份MATLAB小程序面向风能行业工程师、风电项目研究者及学习风速统计建模的学生,用于对风电场实测风速数据进行两参数威布尔分布拟合与参数估计。压缩包内共1个文件,为weibull1.m脚本,体积约436B,属于轻量级可直接…

2026/10/19 13:14:38 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →