ARTICLE DETAIL

资讯详情

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

SpringBoot图书管理网站开发实战:从数据库设计到部署全流程

SpringBoot图书管理网站开发实战:从数据库设计到部署全流程 SpringBoot图书管理网站这个项目算是我接触过的毕业设计选题里最经典、也最稳的一个。每年计算机相关专业的学生做毕设图书借阅管理系统都是被选烂了的题目但正是因为经典它的技术栈覆盖特别完整后端框架、数据库设计、增删改查、权限控制、事务处理、以及最终的打包部署一条链路走下来基本把Java Web开发的核心能力都串起来了。这篇文章我就结合自己做类似项目的经验把基于SpringBoot的图书管理网站从设计到落地全过程拆开讲一遍包括项目结构、数据表设计、核心业务逻辑、开发环境配置、以及调试部署时最容易踩的坑整个过程都是可复现的。不管你是拿它做毕业设计还是想找个完整的SpringBoot练手项目这篇文章都能给你一套可以直接上手的完整参考。先说一下总体情况。这种图书管理网站功能上通常不会做得特别复杂核心就是围绕“图书、读者、借阅、归还”四条线展开。前端不需要上什么大框架后端用SpringBoot配合MyBatis或MyBatis-Plus操作数据库前端用Thymeleaf模板引擎加Bootstrap就能做出很规范的页面。整个项目体积不大但五脏俱全用来搞毕设或者系统学习SpringBoot再合适不过。1. 项目整体设计与技术选型思路1.1 为什么选SpringBoot而不是传统的SSM或SSH很多学生在选题时会纠结到底用SSM还是SpringBoot。我个人的建议是直接上SpringBoot理由很实在省出来的时间足够你把论文多写两版。传统SSM项目需要大量XML配置什么spring-mvc.xml、spring-mybatis.xml、web.xml一个都不能少而且版本之间兼容性问题一大堆。SpringBoot的核心逻辑就是“约定优于配置”它通过starter依赖把常用的配置直接封好你只要引入spring-boot-starter-web内嵌的Tomcat就自动帮你把Web环境跑起来了。对图书管理系统这种业务型项目来说SpringBoot能让你把精力花在业务代码上而不是浪费在配置文件的报错上。另外还有一点很重要SpringBoot项目的结构清晰Controller、Service、Mapper分层明确答辩的时候老师问起来也容易讲清楚代码的可维护性比传统SSM强很多。1.2 具体技术选型与技术栈分工我这套项目里用的核心技术栈如下后端基础框架是SpringBoot 2.x具体版本用的2.3.4.RELEASE这个版本非常稳定后续集成MyBatis-Plus不会有兼容问题。ORM层用的MyBatis-Plus它比原生MyBatis好在不需要写大量重复的CRUD SQL内置的BaseMapper直接提供了增删改查方法对于图书管理这种以单表操作为主的系统来说能省很多事。数据库用MySQL 5.7如果电脑装的是MySQL 8.0也没问题修改一下驱动依赖即可。前端页面用Thymeleaf渲染加Bootstrap 4做样式框架配合jQuery操作页面交互。实现导航栏、表格、分页、模态框这些组件完全够用而且不需要额外引入Vue这类重前端框架。关于前后端分离这个问题毕设场景下我不太推荐。前后端分离意味着你要同时维护两套工程部署时要处理跨域答辩演示时要同时启动前端后端两个服务数据交互逻辑还得多一层JSON序列化。用Thymeleaf模板引擎把前后端放在同一个项目里启动一个应用就能跑通全部功能复杂度低很多。虽然显得不那么“现代”但对一个以数据库设计和业务逻辑为考察重点的毕设来说这是最务实的方案。1.3 功能模块划分与系统角色整个图书管理系统按功能划分成以下几个模块管理员登录认证模块负责管理员的登录、密码加密存储、会话管理。图书管理模块包括图书信息的添加、编辑、删除、列表查询以及按书名、作者、ISBN等条件模糊搜索。读者管理模块管理使用图书系统的读者信息包括办证、信息修改、注销等。借阅管理模块这是整个系统的业务核心包含借书、还书、借阅列表查询、借阅状态管理。分类统计模块统计馆藏图书数量、借出数量、超期未还的数量等给管理员一个直观的数据总览。系统角色我建议只设计一种管理员角色就够了。如果做成学生和管理员双角色登录涉及权限框架的引入比如Spring Security或Shiro项目复杂度会陡增论文篇幅也会翻一倍。单管理员角色配合会话拦截器一样能把权限控制讲明白。2. 数据库设计与核心表结构2.1 需求分析梳理与实体关系定位数据库设计是整个系统的地基很多学生把精力放在页面和代码上结果数据库字段设计得一塌糊涂导致后面代码反复改。别图快先把表设计搞清楚。图书管理系统的核心实体有四类图书、读者、分类、借阅记录。图书与分类是多对一关系一本图书属于一个分类一个分类下有多本图书。图书与读者通过借阅记录产生联系一本图书可以被多个读者借过一个读者可以借多本书本质上是一个多对多关系中间通过借阅记录表解耦。这四张表就能覆盖系统的主要业务场景一张多余的都不需要。2.2 核心数据表的字段结构设计直接给出我在实际项目中使用的表结构大家可以直接拿去做数据库脚本。图书表t_book表名字段有id主键自增、book_name书名、isbnISBN号、author作者、publisher出版社、category_id外键关联分类表、total_num馆藏总数量、current_num当前可借余量、book_photo封面图片路径、book_desc图书简介、create_time入库时间。current_num这个字段要特别注意它是借书操作判断图书是否可借的重要依据。读者表t_reader字段有id、reader_no借阅证号、reader_name姓名、sex性别、phone手机号、password登录密码这里的密码要存加密后的密文不能存明文、id_card身份证号、create_time办证时间。分类表t_category字段有id、category_name分类名称、category_desc分类描述。在建表时预置好常用分类比如文学、历史、科技、艺术、经济等方便测试时使用。借阅记录表t_borrow字段有id、book_id外键图书ID、reader_id外键读者ID、borrow_time借出时间、return_time应还时间和实际还书时间要区分开、actual_return_time实际还书时间、status借阅状态状态可以用数字标记0代表借出中1代表已还2代表超期未还。外键约束我在项目里建了但实际开发中用MyBatis-Plus做联表查询时会发现外键不需要也能查。不过建上外键在论文里更好画ER图老师看起来也更规范一举两得。2.3 借阅流程的SQL逻辑设计借书和还书的数据库操作是整个系统的业务核心逻辑理清楚代码就简单了。借书时的事务逻辑是先根据book_id查询图书的current_num如果当前余量小于等于0说明书不可借拒绝借出如果余量足够就执行update t_book set current_num current_num - 1 where book_id ?减少余量同时向t_borrow插入一条借阅记录状态设为0借出时间取当前时间应还时间一般是当前时间加30天。这个流程涉及两张表的修改操作必须加上事务控制否则扣了库存却插不进记录数据就乱了。还书时的事务逻辑刚好相反根据借阅记录ID查询借阅信息校验确实是借出状态后执行update t_book set current_num current_num 1 where book_id ?恢复余量同时更新借阅记录的actual_return_time为当前时间status改为1。超期判断不用单独开定时任务去扫描查询借阅列表时用一条SQL就能实时算出来判断status 0且return_time NOW()满足这两个条件的就是超期未还。2.4 初始化数据与测试数据准备数据库建好后测试数据很关键。不建议直接复制网上那种几万条数据维护麻烦不说查询展示还容易卡顿。我当时是准备了一套手写的初始化脚本包含1个管理员账号、5个图书分类、20本图书、10个读者基本covering了所有场景。管理员账号密码不能明文录入数据库需要先在代码里用MD5工具类加密后再插入或者预先算好加密串写死在SQL里。我自己是在写项目工具类时顺手输出了一份加密后的结果直接粘到SQL脚本里的。用户名是admin密码是123456加密后存入数据库登录时拿用户输入的密码同样加密后去比对。这种方式在答辩时好解释也不涉及Spring Security那套复杂的过滤器链。3. 核心功能实现与关键代码演示3.1 管理员登录认证与拦截器实现登录功能是所有模块的入口。Controller层接收用户名密码调用Service层按用户名从数据库查出管理员记录将查询到的记录中的密码和前端传来的密码做加密比对。匹配成功就把管理员信息存入Session同时设置Session的有效期跳转到系统主页面匹配失败就返回错误提示留在登录页。拦截器的实现我用的SpringBoot内置的HandlerInterceptor注册时拦截除登录接口、静态资源外的所有请求。拦截器里的处理逻辑就一段判断Session里有没有管理员对象没有的话直接重定向到登录页。这样能保证未登录用户无论如何都访问不了系统内部页面。这里有个小知识点Thymeleaf页面引用的CSS、JS等静态资源默认不会走Controller但拦截器会拦所以注册拦截器时一定要记得排除静态资源路径否则页面样式全丢。3.2 图书信息的增删改查与模糊检索图书管理模块是典型的CRUDMyBatis-Plus封装好了基础方法自己需要处理的只有分页和模糊查询两个场景。分页查询直接使用MyBatis-Plus内置的分页插件一个Page对象配合QueryWrapper就能把页码、每页条数、总记录数都算好。前端接收到的数据通过Thymeleaf的th:each循环渲染到Bootstrap表格里底部放分页导航条。模糊查询是图书列表页的标配功能。按书名、作者、ISBN组合条件查询代码上用QueryWrapper.like()方法就能实现多条件拼接。用户输入的关键词不是空时才拼接这个条件用字符串判空配合if逻辑控制即可。注意书名和作者条件之间要用and连接这地方想清楚查询逻辑就不会出错。删除图书时建议做成软删除或者加确认弹窗防止误删数据。Bootstrap的模态框结合jQuery可以做出一个二次确认效果点击删除时弹窗提示确认后再向后端发送删除请求。这种交互细节虽小但在演示系统中很加分答辩时老师看着也舒服。3.3 借书、还书与库存一致性的事务控制借阅功能的核心难点是库存一致性我直接说实现思路。借书操作写在BorrowService的borrowBook方法里方法上标注Transactional注解让整个操作纳入Spring的事务管理。方法内先查询图书当前余量如果余量大于零执行扣库存SQL然后插入借阅记录两条数据库操作同生共死。中途只要有一个步骤抛异常事务就自动回滚不会出现库存变了但记录没生成的情况。还书操作同理恢复库存和更新借阅记录状态要放在同一个事务里。需要注意一个边界情况如果同一本书被同一个读者借了两次比如借了《三体》上册又借了《三体》下册还书时要根据借阅记录ID而不是图书ID去更新状态只还其中一本时另一本状态不受影响。这个细节用错字段就会导致还书状态错乱建议在代码里多一个校验处理。3.4 前端页面搭建与页面渲染细节前端页面我用了统一布局顶部是导航栏左侧是侧边栏菜单中间是内容区域底部是页脚。Thymeleaf的th:fragment可以把公共部分提取成碎片每个页面直接引用这样不用在每个HTML里重复写导航代码。页面渲染时注意Thymeleaf对空值的处理比较严格。如果某个字段在数据库里是null页面直接渲染会报错或显示空白。比如图书封面没传时book_photo字段为空th:src就会生成一个坏链接。稳妥的做法是给默认图片路径或者用th:src${book.bookPhoto} ?: /images/default.jpg这种写法兜底。表格数据循环渲染时注意给每一行的操作按钮加上唯一的ID标识通常用book.id拼接方便jQuery根据ID定位目标行。借书、还书、编辑、删除这四个操作按钮我全都是通过模态框配隐藏域的方式传参的页面刷新后不会出现参数残留问题。4. 开发环境搭建、调试与部署实录4.1 本地开发环境准备要点开发环境这部分环境配不好项目都启动不了。先说版本搭配这也是我踩坑最多的地方。JDK版本必须用1.8这个项目是基于Java 8写的换JDK 11或17可能导致SpringBoot 2.3某些依赖不兼容。Maven用3.6以上版本IDEA自带的Maven可能版本过低。MySQL建议5.7如果本机已经装了8.0则需要把驱动从mysql-connector-java换成mysql-connector-j时区配置也有区别这个后面会细说。数据库工具推荐用Navicat直接用图形化界面执行SQL脚本即可。创建数据库时注意字符集一定要选utf8mb4排序规则选utf8mb4_general_ci不然后续中文数据显示全是问号。4.2 application.yml核心配置解读下面是项目里application.yml的核心配置做同类项目可以直接套用server: port: 8080 servlet: context-path: / spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/book_manager?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 thymeleaf: cache: false suffix: .html prefix: classpath:/templates/ mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: id-type: auto几个关键点逐个解释serverTimezoneAsia/Shanghai这条必须加MySQL 8.0 的驱动默认时区跟本机不对的话连接就会报The server time zone value的错误。useSSLfalse是防止本地连接时出现SSL握手警告。characterEncodingutf8解决中文乱码问题这个参数不加插入数据库的中文很可能变成问号。Thymeleaf的cache: false在开发阶段一定要设置这样改了HTML不用重启项目刷新页面就能见效调试效率翻倍。MyBatis-Plus的日志输出配置让我们在控制台直接看到执行了哪些SQL语句排查问题的时候特别好用。4.3 项目的完整运行流程整个项目从0到1跑通的步骤我总结如下第一步用Navicat新建数据库book_manager字符集选utf8mb4然后运行项目附带的book_manager.sql脚本导入表和测试数据。第二步打开IDEA选择File - New - Project from Existing Sources导入项目选择Maven模式。等待Maven下载完所有依赖这步网络不好可能要等几分钟耐心点。第三步修改application.yml里的数据库用户名和密码改成自己本机MySQL的用户名密码。第四步右键启动类BookManagerApplication.java运行main方法。控制台出现Started BookManagerApplication就说明启动成功。第五步浏览器访问http://localhost:8080不出意外就能看到登录页面输入admin账号和密码即可进入系统。4.4 项目打包与生产环境部署项目做完要部署上线常见的需求是把项目打成可执行jar包。在IDEA的Maven面板双击package或者在项目根目录执行打包命令mvn clean package -DskipTests打包完成后target目录下会生成一个jar文件这个文件就是完整的可运行程序。把它传到自己服务器或者云主机上执行java -jar book-manager-0.0.1.jar服务就启动了。注意服务器上要用nohup命令让程序在后台运行防止关闭终端时进程被kill掉nohup java -jar book-manager-0.0.1.jar run.log 21 默认占用8080端口如果想改端口启动时加上启动参数java -jar book-manager-0.0.1.jar --server.port8081这种部署方式对毕设演示完全够用。如果追求更好的生产环境可以用云服务器搭Nginx做反向代理再加HTTPS证书。不过说实话这类项目重心在业务逻辑设计只要jar包能稳定跑起来就已经达到毕设的交付标准了。5. 常见问题排查与避坑经验实录5.1 启动失败类问题与解决方案这里我把实际操作中遇到频率最高的几类报错整理成一个速查表方便大家对照排查启动报Port 8080 was already in use说明8080端口被占用。解决办法是改配置文件里的端口或者在启动前找到占用端口的进程并kill掉。Windows下可以用netstat -ano | findstr 8080查到进程PID然后去任务管理器结束它。启动报Cannot connect to MySQL server基本是数据库连接配置有问题。优先检查application.yml里用户名和密码是否填对了再检查MySQL服务有没有启动。我在实际帮人排查时发现80%的人都是密码写错了或者忘了启动MySQL服务。启动后访问http://localhost:8080404先看控制台启动日志确认服务是否真的启动成功。如果日志里有一堆扫描包路径的警告通常是启动类的位置放错了。SpringBoot默认扫描启动类所在包以及子包Service、Controller、Mapper必须放在启动类的同级或下级包中放错位置就扫描不到页面全部404。5.2 中文乱码问题排查中文乱码有三个层次每个层次的原因和解决办法都不一样。页面显示乱码检查HTML文件的编码是不是UTF-8IDEA右下角能看到当前文件的编码格式。如果不是UTF-8用File - File Encoding转换成UTF-8编码。数据库存进数据后中文变问号检查数据库和表的字符集是否utf8mb4以及JDBC连接URL中的characterEncodingutf8是否拼写正确。页面请求后端返回的数据乱码检查application.yml中Servlet编码配置加一个spring.http.encoding.forcetrue强制使用UTF-8。这三个层次全部排查完中文乱码问题基本能根治。5.3 页面样式丢失与静态资源加载失败登录页能打开但页面没有样式是拦截器把静态资源拦截了或者模板里静态资源路径写错了。解决办法就是在注册拦截器时显式排除/**/*.css、/**/*.js、/**/*.png等静态资源路径。Thymeleaf页面里引用静态资源要注意写法推荐用{/css/style.css}它会自动拼接上下文路径。JavaScript里引用URL不要用绝对路径在Servlet环境里很容易漏掉ContextPath导致动态拼接出来的请求地址404。稳妥的写法是在JS里获取根路径var ctx [[{/}]]之后所有AJAX请求都基于这个前缀拼接。5.4 MyBatis-Plus使用中容易掉进的坑用MyBatis-Plus的时候有几个细节特别容易出错都是新手必踩的坑。第一个是实体类字段名映射问题。数据库字段如果带下划线比如book_name实体类字段要保证驼峰写法bookNameMyBatis-Plus默认开启驼峰转换但如果关闭了这个配置查询结果全部是null。第二种情况是current_num这种字段实体类对应currentNum踩坑了才知道配置的重要性。第二个坑是逻辑删除字段。图书或读者记录如果设置了逻辑删除用selectById查询时删除过的记录默认查不出来这是框架行为。如果测试数据被逻辑删了导致页面上看不到可以改配置或者查询时显式增加过滤条件。别慌先查清楚原因再动手。第三个坑是时间字段的填充。借阅记录的borrow_time和return_time这些时间戳字段建议在实体类上用TableField(fill FieldFill.INSERT)指定自动填充或者在业务代码里手动set当前时间。我当时图省事在SQL里写NOW()后来改代码时发现可维护性很差建议还是用Java 8的LocalDateTime来处理代码更规范论文里也更好写。5.5 论文文档撰写与技术答辩准备最后说一下这个项目配套论文的事情。1万字以上的论文并不难写重点是结构清晰。建议论文的章节安排是绪论、相关技术介绍、系统可行性分析、需求分析、系统设计、数据库设计、系统实现、系统测试、总结展望。其中数据库设计和系统实现部分是最核心的篇幅占比一定要把技术点写深、写透把JPA和MyBatis-Plus两者的差异、事务控制原理、数据一致性问题作为论文中的技术亮点。答辩时老师最常问的几个问题提前准备好就不慌。为什么选SpringBoot框架、数据库为什么选MySQL、图书库存和借阅记录怎么保证一致、系统有哪些不足的地方还能怎么改进。最后一个问题答得好很加分我当时就是提了系统没有引入Redis缓存、没有做消息队列、没有实现分布式事务但刚落完地就把话题引回SpringBoot单体架构为主流的应用背景老师听了很认可。我个人在实际操作中的体会是这种图书管理系统看似简单但它把Java Web开发涉及的核心知识点都串起来了从环境搭建、数据库设计、业务编码再到最后打包部署完整走完一遍对SpringBoot的理解会踏实很多。如果你正打算拿这类项目练手或者做毕设遇到页面报错、数据库连不上、部署起不来这些问题千万别急着怀疑自己先把日志看清楚一段一段排查这些坑都是每个做项目的人必经的路。最后再分享一个小技巧项目跑通之后记得备份一份能正常运行的完整包后续怎么折腾都不会影响交付版本这是毕设阶段最稳妥的习惯。
返回列表