ARTICLE DETAIL

资讯详情

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

SpringBoot+Vue图书管理系统:前后端分离毕设完整设计与核心实现

SpringBoot+Vue图书管理系统:前后端分离毕设完整设计与核心实现 SpringBoot加Vue的图书管理系统在Java Web毕设里算是最经典的一道题了。每年到毕业季十个做Java的毕业生里至少有两三个会落在图书管理或者类似的“XX管理系统”上。这个题目的好处在于业务逻辑清楚不绕弯子CRUD能完整覆盖同时又可以往权限、分页、事务、文件上传这些方向做深度扩展既保底又能出彩。我说的这套项目是带完整源码、SQL脚本和接口文档的前端Vue后端SpringBoot前后端彻底分离接口走RESTful风格。不管你是正要选毕设题目、打算拿一套项目练手熟悉前后端交互还是想学SpringBoot和Vue到底怎么配合落地这套东西都很值得从头到尾过一遍。先说点实在的会写接口的人和会设计接口的人差距就在那些“看着简单但你没想到”的细节上。这个项目里最值得研究的不是book表那几条增删改查而是登录鉴权怎么做、统一返回结构怎么定、分页条件查询怎么组合、借书还书的事务边界在哪儿。这篇文章我会把项目里面的核心设计逻辑、代码结构、数据库脚本要点、接口文档规范以及我在实际跑这套项目过程中踩过的坑全部拆开讲一遍给你一份能直接抄作业、也能让你在答辩时有的说的完整参考。1. 项目整体设计与技术选型思路1.1 为什么图书管理系统是毕设常青树图书管理系统经久不衰根本原因是它踩中了毕业设计的“黄金区间”。从业务角度看图书管理涉及用户、图书、分类、借阅记录、公告、统计报表这些典型实体天然具备多表联查、分页、条件筛选、状态流转在馆、借出、逾期、已还等场景这些刚好能把数据库设计和后端业务逻辑的基本功测出来。从技术角度看它又不会难到“指导老师觉得你过度设计”的地步。比起电商系统那套商品-订单-库存-优惠券的复杂状态机图书管理的状态流转简单、边界清晰拿它来展示SpringBoot的基本功非常合适。更关键的是它的扩展性。同样是图书管理系统你可以往上加Redis缓存热门图书加ElasticSearch做模糊搜索加Spring Security细化权限甚至可以挂一个扫码借书的移动端入口。这套项目做出来之后在答辩环节有非常充分的“可演进”话题不会出现“做完了没东西可说”的尴尬局面。1.2 技术选型为什么是这套组合后端选SpringBoot这基本是Java方向毕业设计的默认答案。SpringBoot让配置变得非常轻内嵌Tomcat直接打jar包就能跑自带健康检查、指标监控这些生存能力不需要你再折腾外部容器。版本上我个人建议用2.7.x系列。为什么不用3.xSpringBoot 3.x必须配JDK 17以上而很多学校机房、还有学生自己电脑上的环境都还停在JDK 8直接拿3.x做环境都要折腾半天。2.7.x配JDK 8可以说是兼容性最强、网上资料最多、踩坑成本最低的组合。ORM层推荐MyBatis-Plus原因很简单它对单表CRUD几乎是零成本内置的分页插件和LambdaQueryWrapper写条件查询非常顺手。你不用像原生MyBatis那样为每一张表老老实实写一堆mapper.xml基础SQL由它自动生成复杂的多表查询你再用注解或XML控制。这套组合在Java毕设届的普及率太高了出任何问题都能搜到解决方案。前端用Vue 2加Element UI。虽然Vue 3已经是大趋势但考虑到毕设项目要保证资料易查、组件生态丰富、部署方便Vue 2的稳定性和Element UI的成熟度依然值得信赖。Vue 2配合Vue Router和Vuex/或者简单的localStorage方案可以非常清晰地展示SPA单页应用的完整交互链路。Element UI的表格、对话框、表单校验组件做了大量封装对不常写前端的人来说非常友好。数据库选MySQL加Navicat或者DataGrip作为管理工具这个没人有异议。字符集一定要选utf8mb4别问为什么等你哪天在图书备注字段里存了个emoji回来看这句话你就懂了。1.3 数据库设计与接口风格的相互配合这套项目的数据库设计思路是用户体系管理员普通读者和图书核心业务分离借阅记录作为中间业务表贯穿两类角色。一共五张核心表用户表、图书表、分类表、借阅记录表、角色表外加用户角色关联表和公告表。接口风格选RESTful资源用名词表示操作靠HTTP动词区分GET代表查询、POST代表创建、PUT代表修改、DELETE代表删除。前端Vue项目通过axios发请求后端统一返回JSON。这里最核心的设计决策是定义一个统一的返回体里面包含状态码、提示信息和数据体。这个看似简单的事情决定了前端所有接口调用的体验和联调效率后面我会专门拆开讲。2. 系统架构与数据库核心设计2.1 前后端分离的整体运行结构这套项目的运行结构是标准的前后端分离前端用Vue cli构建运行在8080端口开发模式下通过proxyTable把/api请求转发到后端后端SpringBoot运行在9090端口MySQL跑在3306。前端拿到的所有数据都来自后端接口后端不关心页面长什么样只负责提供结构化数据。前后端通过HTTP协议通信这里就不可避免地牵出跨域问题。实际项目中我在后端配置了全局CORS允许前端开发服务器的地址访问。开发阶段后端开CORS、前端配代理双管齐下等上线之后前端打包成静态文件放在Nginx由Nginx反向代理转发API请求这样就不存在跨域问题了。这个过渡方案在毕设项目里最省心后面我会在踩坑部分细讲为什么本地联调时会出现各种看不懂的跨域报错。2.2 核心表结构与字段设计数据库脚本里最关键的部分是基础表的字段设计这里我把它拆开讲。用户表sys_user设计核心字段字段类型说明idbigint主键雪花算法生成usernamevarchar(50)登录名唯一索引passwordvarchar(100)BCrypt加密后的密文real_namevarchar(30)真实姓名借书需要用到phonevarchar(20)手机号statustinyint1正常 0禁用图书表books是核心资源表包含书名、作者、出版社、ISBN、分类ID、馆藏数量、当前可借数量、上架状态、封面图URL这几类字段。其中容易忽略的是“当前可借数量”这个字段很多新手直接把总数当可借数去用等到写借阅逻辑就会很痛苦——因为借书要验证库存可借数量必须被真实扣减。所以我在表里把total_count和available_count分开每次借出把这个字段减一每次归还把它加一这样查询“可借图书列表”就是一条简单的条件查询不需要去临时汇总借阅记录表。借阅记录表borrow_record是业务核心字段包括借阅人ID、图书ID、借书时间、应还时间、实际归还时间、状态。状态是这套系统最重要的业务字段0借出中、1已归还、2逾期归还、3超期未还。为什么不把状态存在借阅表之外因为每次用户点“我的借阅”API就是要能从这张表直接把这四种状态都查出来。分类表category很普通但要注意一点预留parent_id字段万一你想做二级分类就不用改表结构了。角色和用户角色关联表是我为了演示“不同权限看到不同菜单”加的普通读者进前台图书查询页面管理员去后台管理界面路由守卫根据角色控制这也是答辩时的一个加分点。2.3 数据流转从登录到借书你登录时前端把用户名密码POST到/api/auth/login后端校验用户名存在、密码BCrypt匹配然后签发一个JWT令牌返给前端前端把token存起来。之后的每一次请求前端都会把这个JWT放在HTTP头部的Authorization字段里。然后你搜索图书前端把“书名关键字分类借阅状态”作为查询参数传给/api/books后端用MyBatis-Plus的条件构造器动态拼SQL。找到书之后点借阅前端POST一条借阅请求到/api/borrow/records请求体里面带bookId和借阅天数。后端第一步用图书ID查出这本书并校验available_count大于0第二步把可借数量减一第三步往借阅记录表插入一条借出记录。这两步放在一个事务里任何一个失败都整体回滚避免出现“记录插进去了但库存没扣”的脏数据。这一套链路里其实藏着三个经典考点JWT无状态鉴权、条件分页查询、事务一致性。你在答辩的时候把这些逻辑讲清楚老师基本就没有什么可问你更细节的东西了。3. 后端SpringBoot核心实现拆解后端源码的目录结构是典型的分层架构com.example.library ├── controller // 接口层 ├── service // 业务层 ├── mapper // 数据访问层 ├── entity // 实体类 ├── common // 统一返回体、全局异常、工具类 ├── config // 配置类CORS、MyBatis-Plus分页插件等 └── security // JWT拦截、登录鉴权3.1 分层架构的角色边界后端代码最重要的设计约束是“每一层只干自己该干的事”。Controller层只负责接收参数、调用服务、包装返回结果不写业务判断Service层负责业务逻辑组合、事务控制、状态校验Mapper层只负责数据库读写。很多新手项目我一眼就能看出来问题Controller里堆了一堆业务判断Service又返回Map到处拼接数据Mapper里再搞一堆嵌套子查询。这种代码的特点是跑起来正常、一旦要改功能就得全局重来。这套项目里一个比较典型的例子是还书操作。还书不只是“把记录状态改成已归还”它还需要校验当前时间是否逾期、计算逾期天数、把图书表里available_count加一、更新借阅记录状态。这些步骤全部放在Service层的borrowService.returnBook(Long recordId)里加上Transactional注解保证一致性。Controller只需要接收recordId然后调用这个方法然后返回统一结果非常清爽。3.2 JWT登录认证与全局拦截器登录认证这块是很多毕设项目的软肋动不动就是前端记一个userId传给后端后端也不查验身份就直接信了。这套项目的做法是标准JWT无状态认证。登录成功后我签发一个token往里面塞三个信息用户ID、用户名、角色标识。密钥硬编码在yml配置里当然这只是毕设方案生产环境里应该用独立的密钥管理体系。JWT里的过期时间我设置成了7天在缓存里存当前用户的信息同时在数据库里维护一个token版本字段。这套处理在入门项目里已经足够展示你对认证机制的理解了。后端注册了一个HandlerInterceptor拦截所有/api/**请求但排除掉/api/auth/login和/api/books/public这类公开查询接口。拦截器做的事情很单纯从Header里取出token解析校验签名和过期时间把用户信息放进ThreadLocal方便Service层随时取用当前用户。如果token解析失败直接返回401状态码让前端跳回登录页。前端Vue Router的路由守卫和后端拦截器形成了双保险页面层面没有token不准进管理界面接口层面没有合法token就直接拒绝。这里在答辩时值得注意的是准确解释“前端路由守卫只是用户体验控制后端接口校验才是真正的安全边界”。3.3 统一返回体与全局异常处理统一返回结构是整个前后端联调中使用频率最高的约定{ code: 200, message: 操作成功, data: {} }Code用200表示成功400表示参数错误401表示未登录或token失效500表示服务器内部错误。这个体例我在所有接口里保持完全一致前端axios响应拦截器只需要判断code是不是200不是就统一弹出错误提示根本不需要在每个页面里重复写错误处理逻辑。和统一返回配套的是全局异常处理器。我在项目里自定义了一个BusinessException业务上所有“可预期的错误”——比如库存不足、图书不存在、用户被禁用——都主动抛出这个异常并带上具体错误信息。全局异常处理器捕获到它之后返回code400的JSON。而其他异常统一走code500并且日志里记录堆栈。这样的好处是后端代码里不用疯狂写return error()来判断分支错误处理集中在异常处理器里完成代码整洁度和可维护性都高了一个档次。3.4 分页查询与条件组合的实现分页查询是图书列表的核心功能也是MyBatis-Plus展示价值的场景。前端传过来三个查询参数keyword书名模糊搜索、categoryId分类筛选、availableOnly只看可借。LambdaQueryWrapperBooks wrapper new LambdaQueryWrapper(); wrapper.like(StringUtils.hasText(keyword), Books::getTitle, keyword) .eq(categoryId ! null, Books::getCategoryId, categoryId) .eq(Boolean.TRUE.equals(availableOnly), Books::getAvailableCount, , 0) .orderByDesc(Books::getCreateTime); PageBooks page new Page(current, size); booksMapper.selectPage(page, wrapper);这里值得注意的设计是eq方法的第一个参数是布尔条件。动态查询里经常出现“用户没传分类就不按分类查”的情况。用这种写法扩展性很好避免了传统方法里一堆if判断拼接wrapper的麻烦。MyBatis-Plus返回的Page对象里自带total、pages这些分页元数据前端表格组件可以直接消费。关于分页需要注意的是不要把MyBatis-Plus的分页插件忘了配。如果忘了配置PaginationInnerInterceptor你会发现selectPage查出来的total永远是0数据却正常返回。这个问题每年都有无数人踩所以我提前说一句。4. 前端Vue核心实现逻辑4.1 项目结构与目录规划前端源码用Vue CLI初始化项目src目录按职责划分了几个模块api每个模块的接口调用全部集中在这里管理。好处是当后端接口地址改了你只需要改一个文件。router路由配置里面配了路由守卫和每个页面的加载方式。views页面组件按业务域拆分成login、admin、reader这几个目录。components公共组件比如图书信息卡片、分页组件、状态标签。utils工具函数包括axios实例的封装。store全局状态管理用来存放用户信息和菜单权限。这套目录结构的核心意图是让“接口调用”和“页面展示”完全分离。一个Vue页面里不应该出现axios的调用逻辑它应该只负责渲染数据的来龙去脉全在api层。这种分离对后期维护非常重要也方便你把项目拆开给同伴协作。4.2 路由守卫与权限控制前端权限控制分两层。第一层是“有没有登录”第二层是“角色允不允许访问这个页面”。路由配置里每个页面在meta里标注角色要求。比如admin下的用户管理页面meta.roles是[admin]普通读者的借阅页面meta.roles是[reader]。路由守卫在每次页面跳转时执行逻辑router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (!token) { if (to.path ! /login) { next({ path: /login }) } else { next() } } else { if (!store.state.userInfo) { // 刷新页面时用户信息丢失重新请求获取 store.dispatch(fetchUserInfo).then(() { if (to.meta.roles !to.meta.roles.includes(store.state.userInfo.role)) { next({ path: /403 }) } else { next() } }) } else { next() } } })这个守卫逻辑要解释清楚一个设计决策为什么页面刷新之后要重新请求用户信息因为用户信息存在Vuex里是内存态页面一刷新就丢了而token在localStorage里是持久化的。不能用持久化的token去替代内存里的用户信息因为token里只有用户ID和角色但你页面展示时经常需要用户名、头像、手机号这些详细信息。重新请求一次/auth/userinfo接口根据token拿回完整资料是行业标准的做法。4.3 axios封装与token注入axios实例被统一封装在utils/request.js里核心是两层拦截器。请求拦截器每次发请求前自动从localStorage取token放到Authorization头。这保证了任何请求都不需要业务代码里手动带token避免遗漏。响应拦截器统一处理三种情况code为200时直接返回datacode为401时跳转登录页并清空登录状态code为其他值时弹出错误提示。这里的常见坑是如果后端接口返回的HTTP状态码是200但业务code是401前端路由跳转要放在响应拦截器里做而不是放在每个业务页面里单独处理。在这个项目里我约定token失效时后端返回HTTP 401状态码这样响应拦截器的错误分支统一捕获不会有漏网之鱼。5. SQL脚本与接口文档的设计要点5.1 SQL脚本该包含什么这套项目附带的SQL脚本不是简单丢一个建表语句它分了三块。第一块是建库建表库名library_db字符集utf8mb4所有核心表的引擎都是InnoDB。第二块是初始数据包括一个管理员账号admin/admin123几个图书分类十来本示例图书和两条演示借阅记录。初始数据的质量直接影响你前后端联调的速度——如果一本书都没有你前端页面完全空白连报错都看不出来。第三块是索引我在username、isbn、borrow_record的status字段上都建了索引。答辩的时候老师往往喜欢问“为什么这里要建索引”答得出来会非常加分。外键方面这套脚本里我没有建物理外键。这是一个刻意的设计。物理外键在delete和update时会带来锁定和顺序问题实际项目里大规模使用外键的越来越少。我更倾向于用逻辑外键在实体表之间建立业务上的关联由Service层保证数据完整性。你可以在答辩时说出这句话这就是在展示你对“数据库设计与业务权衡”的理解。5.2 接口文档的核心结构接口文档是标题里专门提到的一项对于毕设项目来说一份好的接口文档其实比代码本身更能拉开差距。这套系统接口文档使用的格式是接口名称、URL、请求方式、请求参数、返回示例。核心在返回示例每个接口都给出真实的JSON响应前端照着这个写页面不需要反复问后端同事数据长什么样子。拿分页查询图书这个接口举例文档长这样接口名称分页查询图书列表 URLGET /api/books 请求参数 - current: 页码默认1 - size: 每页条数默认10 - keyword: 书名关键字可选 - categoryId: 分类ID可选 - availableOnly: 只看可借可选 返回示例 { code: 200, message: 操作成功, data: { records: [ { id: 1, title: 深入浅出Vue.js, author: 刘博文, isbn: 9787111643607, totalCount: 5, availableCount: 3, status: 1, categoryName: 前端开发 } ], total: 15, pages: 2, current: 1, size: 10 } }文档里有一个容易被忽略但很重要的细节返回给前端的图书对象里包含了categoryName分类名称而不是只有categoryId。这个看似微小的设计省掉了前端很多额外请求。图书列表页展示分类名字的时候不需要再请求一次分类接口去映射。这就是接口设计里常说的“服务端把视图模型组装好”也是你在自己的接口文档里应该有意遵循的规范。5.3 新增借阅记录的接口示例借阅接口是这个系统业务上唯一的写操作核心文档里给出的示例是接口名称新增借阅记录 URLPOST /api/borrow/records 请求头Authorization: Bearer token 请求体 { bookId: 1, borrowDays: 30 } 返回示例 { code: 200, message: 借阅成功, data: { recordId: 101, dueTime: 2025-08-15 12:00:00 } }返回体里的dueTime是后端计算好的应还时间这样前端不需要自己算日期也避免了前后端时区不一致的问题。所有时间统一用String返回格式yyyy-MM-dd HH:mm:ss不使用时间戳。这样做是为了让前端可以直接展示而不用写转换逻辑同时SpringBoot的Jackson配置也很简单只要在yml里配好spring.jackson.date-format和time-zone就行。要记住一个经验前后端时间格式最容易出乱子统一约定“后端给什么前端展示什么”最稳。6. 开发与联调中的常见坑与排查技巧6.1 跨域报错前端能打开但接口请求失败这是做前后端分离第一个遇到的拦路虎。现象是前端页面正常打开但所有axios请求都被浏览器拦截控制台提示CORS错误。我见过很多人在自己电脑上折腾半天各种代理配置最后发现后端根本没配CORS。解决方案在后端一行代码就能搞定配置一个WebMvcConfigurerConfiguration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/api/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }这里要解释一个关键点allowedOriginPatterns(*)不需要和allowCredentials(true)冲突但如果你用allowedOrigins(*)就会冲突报错因为浏览器不允许在带上凭证信息的请求里出现通配符Origin。这是新手非常容易踩的一个细节。注意生产环境不能这么放开但在毕设开发阶段这是加速效率的正确妥协。6.2 SpringBoot版本过高导致的依赖连锁问题如果你直接用Spring官网初始化项目时选了最新版3.x然后照网上的教程引入了旧版MyBatis-Plus大概率会撞上ClassNotFoundException或者Invalid value type for configurationProperties之类的报错。我的建议是SpringBoot统一用2.7.18MyBatis-Plus用3.5.3以上这组搭配我实测过稳定性很好。另外要注意SpringBoot 3.x环境里很多老教程里的配置类和依赖引入方式都不适用了比如javax.servlet要改成jakarta.servlet。所以做毕设的人如果不想在环境问题上浪费时间就选2.7系列。6.3 日期格式和Long类型精度丢失这套项目里主键用的是雪花ID是Long类型。在Java后端是Long没问题但JSON序列化传给前端JavaScript时超过16位的Long会影响精度前端的数字会失真。经典现象是列表页点某个图书详情时传过去的图书ID会莫名和别的记录冲突。处理方式是在ID字段上加上JsonSerialize(using ToStringSerializer.class)这个Jackson注解让ID以字符串形式发给前端。借阅记录表里关联的bookId、userId也都是同一个处理。改完之后再测试一下前端点击跳转、借阅、归还这些操作就不会再出现ID对不上的问题了。6.4 前端能打开但所有接口404还有一个很常见的坑后端启动正常接口在Swagger里也能看到但前端就是404。排查思路很固定。第一步确认后端项目的Controller是否被SpringBoot启动类扫描到——如果你的Controller放在com.example.library.controller启动类在com.example下面没问题如果Controller包路径和启动类不在同一根包下SpringBoot默认扫不到接口自然全部404。第二步检查前端请求路径和后端RequestMapping是不是完全一致少个斜杠或者多个前缀都会出问题。第三步如果是通过Nginx部署还要检查try_files的配置是否会把带/api的请求错误地路由给前端静态页面。这三步走完百分之九十九的404都解决了。6.5 分页total永远为0这个问题我在3.4节提到过但必须单独再点一次名。忘了配置MyBatis-Plus分页插件是初级选手最常犯的错误。现象是前端表格能显示数据但分页组件显示总数为0点第二页却一样能加载数据看起来非常诡异。解决办法是在配置类里注入一个分页拦截器Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; }忘了配这个拦截器的时候MyBatis-Plus会直接把Page当普通参数处理查询total不会走到COUNT语句。配完之后重启项目问题立刻消失。7. 项目扩展方向与使用建议7.1 三个实用的扩展点如果把图书管理系统看做一个可以不断加血的骨架有三个扩展方向性价比极高。一是导出Excel。你可以在图书列表页加一个“导出当前查询结果”的按钮后端把查询结果渲染成Excel文件用EasyExcel这个库去实现。这个功能看起来不复杂但覆盖了文件流的处理、HTTP响应头设置、前端文件下载处理是个非常成熟的答辩点。二是Redis缓存。热门图书列表、图书分类字典这两种读取频率高、更新频率低的数据是缓存最理想的场景。在启动Redis之后改几行代码访问速度会有肉眼可见的提升。答辩时你可以说场景图书馆大厅大屏展示热门借阅图书每次请求都打数据库太浪费了加缓存可以让响应从100ms降到5ms。三是定时任务处理逾期。可以用SpringBoot自带的Scheduled注解每天凌晨扫描所有“已超应还时间且状态仍是借出中”的记录把它们自动改成“超期未还”。这不需要引入额外组件代码量也不大但能让你的项目比同批毕设多出智能化的感觉。7.2 源码和文档应该怎么用如果你是拿到这套源码开始做毕设我的建议是不要急着改功能先按这个顺序走一遍。第一步把SQL脚本导入MySQL确保数据库表都建好并带上了初始数据。第二步配置后端application.yml里的数据库连接信息注意密码改成你自己的。第三步启动后端用Swagger或者直接用浏览器访问登录接口验证管理员能登录。第四步配置前端npm install安装依赖npm run serve启动开发服务器走通登录、查书、借书、还书这一整条主流程。这个走通流程本身就是一个完整的学习闭环。每个人在做这套操作的过程中对“前端发请求-后端处理-数据库操作-响应回前端”的理解都会上一个台阶。走通之后再动手改需求比如把图书状态颜色改一改增加一个必填校验慢慢你就有底气去接新接口了。接口文档在这里起着地图作用。很多不懂前后端分离的人会问“后端接口到底怎么定义的”文档就是他最好的答疑工具。我在给学弟学妹做毕设辅导的时候几乎每次都是让他们把接口文档从头读一遍再动手写前端页面效果很好。7.3 我在这类毕设项目辅导中积累的经验带了不少人做过这个方向的毕设我总结出三条非常实在的经验。第一条答辩前一定要在非常干净的环境里通跑一遍整个项目。不只是你自己电脑能跑还要预演一遍“老师机器上没有你的开发环境你如何在现场把项目跑起来”。最稳妥的万能方案是用IDEA打开项目启动SpringBoot后端然后用浏览器访问前端打包后的静态文件npm run build或者直接让前端通过Nginx跑起来。提前做一次“环境突然变化”的应急演练答辩现场才不会翻车。第二条把技术栈里每个组件的定位和运行流程背熟练。SpringBoot负责什么、Vue负责什么、MySQL负责什么、JWT在哪个环节起作用这些问题几乎是答辩标配。理解整个数据从浏览器到数据库的完整链路比背代码重要得多。第三条不要因为项目简单就轻视演示脚本。我见过有人代码写得相当不错结果答辩演示时因为图书库存扣成了负数或者还书逾期状态没有触发场面一度非常尴尬。提前用断言式地思路给自己列一遍流程测试普通读者登录、搜索图书、借书成功、库存减少、还书成功、库存恢复、超期还书显示逾期、管理员登录管理页面、新增图书、停用用户。每一个环节都准备好对应的数据和预期结果现场按剧本走稳如泰山。最后分享一个小技巧我再讲一个实际操作中能明显提升体验的小技巧在SpringBoot的application.yml里把Jackson的日期格式化全局配好避免前端显示时间像读书笔记草稿一样难看。spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8配完之后所有LocalDateTime和Date类型的字段都统一按这个格式输出。你不需要在每一个实体类的日期字段上手动加JsonFormat注解。这个细节能让前端展示的借书时间、应还时间全部变成可读性很强的标准格式最重要的地方是——你省去了一堆“为什么日期显示是一串数字”这种无聊排查。这套SpringBootVue图书管理系统在我看来不只是满足毕业设计评分标准的一个答题产物更像是一份浓缩版的企业级Web开发路线图。你把它吃透前后端交互、数据设计、接口规范、权限控制、异常处理这些技能点全都能带进真实项目里。如果你正在用它做毕设或者正在学Java后端请踏踏实实跑一遍主流程再拆开每一层去看看它为什么要这么设计收获会比单纯“能跑”大得多。
返回列表