ARTICLE DETAIL

资讯详情

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

SpringBoot智慧图书馆管理系统:从零搭建到答辩通关全指南

SpringBoot智慧图书馆管理系统:从零搭建到答辩通关全指南 每年到毕业设计选题季“图书管理系统”绝对是SpringBoot方向里出现频率最高的题目之一。这个题目看似简单但恰恰因为太常见反而最容易写平庸——如果只是把增删改查堆上去评委一眼就能看出你是在“凑工作量”。这篇内容我把整个系统的设计思路、数据模型、核心代码、前后端联调、部署上线、答辩避坑全部拆开讲完整还原一个能评优、能讲清楚、能应对追问的智慧图书馆信息管理平台是怎么从零落地的。这个平台本质上解决的是高校图书馆里三件麻烦事图书怎么管、借阅怎么留痕、馆藏数据怎么变成决策参考。对应到系统里就是图书信息管理、读者管理、借阅归还流程、逾期计算、统计分析这五块核心功能。适合谁看呢正在做SpringBoot毕设的学生、想快速搭建一个能跑通全流程的图书管理项目的开发者以及准备转行做Java后端但需要一个完整项目练手的人。我尽量把每个关键决策背后的原因也讲清楚知道“为什么这么做”比“怎么做”更重要。我先说一个整体感受这个题目最大的风险不是做不出来而是做出来之后讲不出东西。很多同学把代码写完就以为万事大吉结果答辩时被问一句“你的借书逻辑是怎么处理并发超借的”就卡住了。所以这篇文章里我不只给代码还会把容易被追问的技术点提前摆出来帮你在答辩之前就把“可能会被问的问题”消化掉。1. 整体设计与思路拆解1.1 先想清楚你要做的是一个“系统”不是一个“页面集合”图书管理系统的通病是页面很多但业务闭环不完整。很多人的设计只有图书列表、新增图书、删除图书然后借书还书就是改一个字段统计就是查个数。这严格来说不叫系统叫“表单合集”。我在设计这个项目时第一件事不是建表而是先画业务闭环。我描述的闭环是管理员录入图书与馆藏副本 → 读者检索图书 → 读者发起借阅 → 系统校验库存与读者状态 → 生成借阅记录并冻结馆藏副本 → 到期前催还提醒 → 读者归还 → 系统计算是否逾期并登记 → 数据沉淀到统计模块。这中间每一步都在改数据、留日志、影响下一步操作这才是“管理平台”该有的样子。第二件事才是选技术栈。SpringBoot是绝对的主干因为它的自动装配和starter机制能让开发者用最少配置拉起一个可运行的Web服务。配合MyBatis-Plus做数据访问因为这类管理系统的SQL并不复杂但CRUD量很大MP的代码生成器和分页插件能省下大量重复劳动。MySQL存业务数据Redis做验证码存储和热点数据缓存这属于常规组合没什么可纠结的。1.2 技术选型背后的取舍逻辑为什么不用SSHStruts Spring Hibernate因为那套体系太老了连现在的面试官都不太愿意在这上面浪费时间。为什么用MyBatis-Plus而不是只用MyBatis因为纯MyBatis需要手写大量ResultMap和XML映射毕业设计时间紧没必要在重复性CRUD上消耗精力。但我要强调一句用了MyBatis-Plus不代表你可以完全不会SQL。借阅排行、逾期统计这种查询往往还是要写自定义SQL因为涉及多表联查和多层聚合MP的Wrapper表达起来很别扭。前端选型上我对毕设项目有一个明确建议尽量选Vue 3 Element Plus做前后端分离不要用Thymeleaf模板渲染。原因有三条第一前后端分离是当前企业开发的主流形态答辩时这个架构本身就是加分项第二Vue生态对组件复用支持更好后台管理系统的表格、表单、弹窗都能组件化第三接口联调会在系统中留下更清晰的接口层评委看代码结构时能一眼看到Controller → Service → Mapper的分层是否清晰。1.3 功能模块怎么划才不会显得“凑数”模块划分要围绕“图书生命周期”和“读者生命周期”两条线展开。我最终定下来的模块结构是这样的模块核心功能关键实体读者管理读者注册、信息维护、状态管理正常/冻结/毕业注销读者表馆藏管理图书元数据维护、馆藏副本管理一册一书一码、出版社/分类维护图书表、馆藏副本表借阅流通借书、还书、续借、预约、逾期处理借阅记录表系统管理管理员账号、角色权限、操作日志管理员表、角色表统计分析图书分类占比、借阅热度排行、读者借阅趋势聚合查询视图这样划分的好处是每个模块都有独立的业务实体和业务状态互相之间通过“馆藏副本编码”连接不会出现一个模块里塞一堆不相干接口的情况。而且每一块在答辩时都能从“业务流程 — 表结构设计 — 接口实现 — 前后端交互”四个层次展开讲内容密度足够高。1.4 智慧图书馆的“智慧”体现在什么地方题目里有“智慧图书馆”这个词很多人的做法是把它当噱头只在标题里写一写。我的理解是这个价值要落到具体功能上。我做了两个设计来支撑“智慧”这个概念。第一个是借阅行为分析。借阅记录表里沉淀了读者、图书、时间三个维度系统会按月份统计热门图书排行、各分类图书借阅占比、活跃读者Top10这些数据从MySQL里用几条GROUP BY语句就能聚合出来再通过ECharts以折线图、饼图的形式呈现。第二个是逾期智能提醒。在还书日期前三天系统会根据借阅记录批量生成“即将到期”的提醒列表管理员确认后可以通过站内信或预留手机号发送通知。这两块不需要引入多高深的技术但能让系统和“管理”产生真正的数据价值对于毕业设计来说性价比非常高。2. 核心细节解析与实操要点2.1 角色权限设计三种角色就够了图书管理系统的角色不建议做太复杂三种角色可以覆盖全部场景系统管理员图书管理、读者管理、系统配置、图书管理员日常借还操作、普通读者检索、借阅、个人中心。三种角色对应三套菜单和接口权限。实现方式上我是用Spring Security JWT做的。为什么不只做一个拦截器判断是否登录因为评委在答辩时一定会问“你怎么控制不同角色的访问权限”如果你只有登录校验没有角色授权这个问题就答不上来。Spring Security JWT的组合是当前生产环境最常用的方案也是面试题的高频考点做进毕设里属于“稳赚”的加分项。权限控制的具体粒度上我建议做到接口级别就够了不需要做到按钮级别。也就是说管理员接口用PreAuthorize(hasRole(ADMIN))做标注读者接口只验证JWT中有无有效的用户身份。按钮级权限需要在前端做指令或路由守卫控制管理系统的价值并不体现在这里投入产出比不高。还有一个细节不要自己设计密码加密算法。密码存储一律用BCrypt它在Spring Security里有现成的BCryptPasswordEncoder哈希自带盐值网上几乎所有专业的Java面试题里问到“密码如何安全存储”时标准答案就是BCrypt。2.2 图书与馆藏副本为什么一个Book不能直接对应一条库存记录这是这个系统里最核心的建模问题。一对多的拆分关系必须想清楚图书是“元数据”馆藏副本是“物理实体”。比如《深入理解Java虚拟机》这本书图书馆里买了3本每本都有独立的条码号。借书时读者借走的是其中一本“副本”不是“这本书”。如果不拆表用一条记录加一个数字库存字段来记录会面临两个问题第一还书时你不知道读者还的是哪一本第二如果同一本书不同副本的破损程度不同你无法记录具体是哪一本出了问题。我设计的表结构是这样的图书表存书名、ISBN、作者、出版社、分类、封面图、简介馆藏副本表存副本条码、所属图书ID、状态在馆/借出/破损/下架。借阅记录表关联的必须是馆藏副本ID而不是图书ID。这样设计下来系统所有的借还流程都会变得非常清晰统计时再根据馆藏副本关联查询图书信息即可。2.3 借书还书的“状态机”怎么设计借阅流程不是简单的“在馆改成借出再改回来”中间存在很多分支状态。我把馆藏副本的状态定义为AVAILABLE在馆、BORROWED借出、RESERVED被预约、MAINTENANCE维修下架。借阅记录的状态定义为BORROWED借阅中、RETURNED已归还、OVERDUE已逾期、LOST丢失。状态流转的规则在Service层严格校验不能随便跳转。比如“借书”这个操作只允许从AVAILABLE流转到BORROWED如果副本状态是RESERVED系统要检查预约人是不是当前读者不是就不能借。“还书”操作必须从BORROWED或OVERDUE流转到RETURNED同时自动计算逾期天数并更新读者信用状态。这个状态机设计好了后续所有接口的代码逻辑都会变得有章可循。2.4 检索功能怎么做到又快又够用图书检索是读者使用频率最高的入口但不能为了“快”上来就上Elasticsearch那属于杀鸡用牛刀。项目里的做法是先基于MySQL的LIKE查询完成基础检索覆盖书名、作者、ISBN三个字段配合MyBatis-Plus的LambdaQueryWrapper动态拼接查询条件。数据量在几万条以内时这个方案的查询性能完全够用。如果想让检索再“高级”一点可以加一个基于数据库内置函数或数据字典的分类筛选。很多同学忽略分类筛选但馆藏资源数字化管理系统里分类是用户最自然的筛选方式。我通常建议在图书表里冗余一个分类ID并在前端用级联选择器实现“一级学科分类 → 二级分类”的筛选。至于全文检索答辩时可以讲“这是一个可扩展方向”不建议真在毕设里做因为思考深度和实现成本不成正比。2.5 “数字化”的几个亮点功能“馆藏资源数字化”这个表述我理解为两件事一是资源的电子化检索二是馆藏数据的可视化呈现。前者通过检索模块和借阅记录查询已经覆盖了后者需要专门做统计接口。我做的统计接口有三个分类统计按中图分类法统计馆藏数量与占比、借阅排行按时间段统计热门图书Top10、读者活跃度按学院或年级统计人均借阅量。这几个接口都用自定义SQL实现典型实现是SELECT book_id, COUNT(*) AS borrow_count FROM borrow_record WHERE borrow_time BETWEEN ? AND ? GROUP BY book_id ORDER BY borrow_count DESC LIMIT 10。这类SQL并不复杂关键在于要让读者养成“用数据说明问题”的习惯而这一点恰恰是毕业设计评审中最看重的能力。还有一个容易被忽略但做完非常出效果的功能Excel批量导入导出。管理员不需要一本一本地录入图书而是按模板批量导入馆藏统计结果也能一键导出成Excel。用EasyExcel这个开源库20行代码就能完成导入导出需求。别小看这个功能它是“数字化管理系统”的经典功能答辩时演示一次批量导入比讲十页PPT都有效。3. 实操过程与核心环节实现3.1 建表SQL这四张表是系统的骨架我直接给出最核心的表结构你可以在此基础上扩展。注意字段注释和索引这在文档交付时是加分项。CREATE TABLE book ( id bigint(20) NOT NULL AUTO_INCREMENT, isbn varchar(20) NOT NULL COMMENT ISBN号, book_name varchar(200) NOT NULL COMMENT 书名, author varchar(100) DEFAULT NULL COMMENT 作者, publisher varchar(100) DEFAULT NULL COMMENT 出版社, category_id bigint(20) DEFAULT NULL COMMENT 分类ID, cover_url varchar(500) DEFAULT NULL COMMENT 封面地址, description text COMMENT 图书简介, create_time datetime DEFAULT NULL, update_time datetime DEFAULT NULL, PRIMARY KEY (id), KEY idx_isbn (isbn), KEY idx_category (category_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT图书基本信息表; CREATE TABLE book_copy ( id bigint(20) NOT NULL AUTO_INCREMENT, book_id bigint(20) NOT NULL COMMENT 所属图书ID, barcode varchar(50) NOT NULL COMMENT 馆藏条码, status varchar(20) NOT NULL DEFAULT AVAILABLE COMMENT 状态, position varchar(50) DEFAULT NULL COMMENT 馆藏位置, create_time datetime DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uk_barcode (barcode), KEY idx_book_id (book_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT馆藏副本表; CREATE TABLE reader ( id bigint(20) NOT NULL AUTO_INCREMENT, reader_no varchar(20) NOT NULL COMMENT 学号/工号, reader_name varchar(50) NOT NULL, password varchar(100) NOT NULL COMMENT BCrypt密文, phone varchar(20) DEFAULT NULL, email varchar(100) DEFAULT NULL, college varchar(100) DEFAULT NULL COMMENT 院系, status varchar(20) NOT NULL DEFAULT NORMAL COMMENT 状态, create_time datetime DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uk_reader_no (reader_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT读者表; CREATE TABLE borrow_record ( id bigint(20) NOT NULL AUTO_INCREMENT, reader_id bigint(20) NOT NULL, copy_id bigint(20) NOT NULL COMMENT 馆藏副本ID, book_id bigint(20) NOT NULL COMMENT 冗余图书ID用于统计, borrow_time datetime NOT NULL, due_time datetime NOT NULL COMMENT 应还时间, return_time datetime DEFAULT NULL COMMENT 实际归还时间, status varchar(20) NOT NULL COMMENT 借阅状态, renew_count int(11) NOT NULL DEFAULT 0 COMMENT 续借次数, PRIMARY KEY (id), KEY idx_reader_id (reader_id), KEY idx_book_id (book_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT借阅记录表;3.2 JWT登录认证的完整链路登录模块我不建议用Session。前后端分离项目用Session要配跨域Cookie策略麻烦而且答辩讲JWT更符合当今行业主流认知。JWT的原理是用户登录成功后后端生成一个包含用户ID和角色信息的Token前端存在本地存储里每次请求在HTTP头里带上Authorization: Bearer token后端用过滤器验证Token有效性并解析出用户身份。核心类的设计是这样JwtUtil负责生成和解析TokenSecurityConfig配置放行白名单JwtAuthenticationFilter在Spring Security过滤链中解析Token并设置SecurityContext。关键代码维度上我要提醒几个容易掉坑的地方第一JWT密钥不能硬编码在代码里即使毕设也要养成好习惯从配置文件读取第二Token要有过期时间一般管理员Token有效期设为2小时读者设为24小时过期后前端拦截401并跳转登录页第三不要把密码放进Token的Payload里放用户ID和角色就够了因为Payload只是Base64编码不是加密任何人解码就能看到内容。登录Service层的核心代码如下public LoginResponse login(LoginRequest request) { // 1. 校验验证码 String cacheCode redisTemplate.opsForValue().get(captcha: request.getUuid()); if (cacheCode null || !cacheCode.equalsIgnoreCase(request.getCaptcha())) { throw new BusinessException(验证码错误或已过期); } // 2. 查询用户 Reader reader readerMapper.selectByReaderNo(request.getReaderNo()); if (reader null) { throw new BusinessException(用户不存在); } if (!NORMAL.equals(reader.getStatus())) { throw new BusinessException(账号已被冻结请联系管理员); } // 3. BCrypt校验密码 if (!passwordEncoder.matches(request.getPassword(), reader.getPassword())) { throw new BusinessException(密码错误); } // 4. 生成JWT String token jwtUtil.generateToken(reader.getId(), READER); return new LoginResponse(token, reader.getReaderName(), READER); }这里顺带说一个逻辑细节为什么要加Redis验证码因为图书管理系统虽然不算高价值系统但登录接口是暴力破解的重灾区。Redis存储验证码并设置5分钟过期可以在不引入复杂防刷组件的情况下挡住大部分脚本攻击。3.3 借书接口的并发控制借书是这个系统里最需要动脑的接口。如果你写的是“查到库存0就减1”那并发请求下一定会出现超借。解决这个问题我用了两个方案数据库层面的乐观锁 业务层面的状态校验。乐观锁的不严谨做法是库存字段加版本号每次更新时UPDATE book_copy SET status BORROWED WHERE id ? AND status AVAILABLE。如果你的馆藏副本表在更新时加上这个WHERE条件并发情况下只有一个请求能更新成功MyBatis-Plus的update方法返回影响行数如果返回0说明已经被别人借走了这就是并发控制。完整借书代码Transactional(rollbackFor Exception.class) public void borrowBook(Long readerId, Long copyId) { // 1. 校验馆藏副本是否存在且在馆 BookCopy copy bookCopyMapper.selectById(copyId); if (copy null || !AVAILABLE.equals(copy.getStatus())) { throw new BusinessException(该副本当前不可借); } // 2. 读者是否存在、是否正常 Reader reader readerMapper.selectById(readerId); if (reader null || !NORMAL.equals(reader.getStatus())) { throw new BusinessException(读者状态异常); } // 3. 查读者当前未归还数量限制最大借阅量 Long borrowingCount borrowRecordMapper.selectCount(readerId, BORROWED); if (borrowingCount MAX_BORROW_COUNT) { throw new BusinessException(已达到最大借阅数量请先归还部分图书); } // 4. 乐观锁更新副本状态 boolean updated bookCopyMapper.updateStatusById(copyId, AVAILABLE, BORROWED); if (!updated) { throw new BusinessException(借阅失败请稍后重试); } // 5. 插入借阅记录 LocalDateTime now LocalDateTime.now(); BorrowRecord record new BorrowRecord(); record.setReaderId(readerId); record.setCopyId(copyId); record.setBookId(copy.getBookId()); record.setBorrowTime(now); record.setDueTime(now.plusDays(LOAN_DAYS)); record.setStatus(BORROWED); borrowRecordMapper.insert(record); }这个接口里有两个细节值得注意Transactional(rollbackFor Exception.class)指定了任何异常都回滚包括自定义BusinessException。如果某个中间步骤失败不会出现“副本状态变了但借阅记录没生成”这种脏数据。另外最大借阅量和借阅天数的常量设定在配置类里不要在代码里写魔法数字。3.4 还书接口逾期计算是必须做的还书接口比借书简单但逾期计算不能省。默认借阅天数是30天续借一次再延期30天。还书时计算实际归还时间和应还时间的差如果大于0就更新借阅记录状态为OVERDUE并把逾期天数写入记录。Transactional(rollbackFor Exception.class) public void returnBook(Long recordId) { BorrowRecord record borrowRecordMapper.selectById(recordId); if (record null || !BORROWED.equals(record.getStatus())) { throw new BusinessException(无效的借阅记录); } LocalDateTime now LocalDateTime.now(); long overDays ChronoUnit.DAYS.between(record.getDueTime(), now); if (overDays 0) { record.setStatus(OVERDUE); // 可选记录逾期天数到读者表并标记信用异常 readerMapper.increaseOverdueCount(record.getReaderId()); } else { record.setStatus(RETURNED); } record.setReturnTime(now); borrowRecordMapper.updateById(record); // 把馆藏副本置为可借状态 bookCopyMapper.updateStatusById(record.getCopyId(), BORROWED, AVAILABLE); }顺便强调一下所有状态流转的操作都要在事务里完成。事务保证了“还书更新借阅记录”和“恢复副本状态”要么都成功要么都失败。如果你分两步裸写SQL一旦第二步抛异常系统里就是一本“查无此书”的记录这个错误在演示现场出现是非常尴尬的。4. 前端联调与部署要点4.1 接口文档与Axios封装前后端分离项目最怕接口对不上。我的经验是后端开发完Controller后立即生成Swagger文档前端照着Swagger的路径和参数定义做开发。Spring Boot引入knife4j对swagger做增强接口列表会自动分组每个接口的请求参数和返回结构一目了然。前端请求层建议做统一Axios实例封装。实例要设置三个核心配置基础路径baseURL指向后端服务地址请求拦截器从localStorage取出Token并加到请求头响应拦截器统一拆包如果是401就跳转登录并清除本地Token。这套封装可以让前端的业务代码完全不用关心Token怎么带、错误怎么弹“关注点分离”在这里体现得很直接。4.2 前后端跨域问题前后端分离联调时遇到最多的问题是跨域有时明明后端接口能通前端一请求就报CORS错误。我的做法是在后端做一个全局CORS配置类允许的来源、方法、请求头统一配置成*开发环境因为毕设阶段不需要过度追求CTF级别的安全限制。但这里有一对矛盾要提前说JWT方案下前端如果用axios带着Authorization头发起请求会触发浏览器的预检请求OPTIONS。这个预检请求不带业务参数如果你的后端没有处理好OPTIONS请求前端会看到“Request failed with status code 403”。Spring Security的配置里需要显式放行OPTIONS请求不然联调阶段你会被这个莫名其妙的问题坑掉整整一天。4.3 打包部署的两种方式毕设演示环境有两种部署方案我建议你至少会其中一种。第一种是最简单的后端用mvn clean package打成jar包java -jar直接跑。这种方式最省事演示时在cmd窗口里启动就行前提是服务器上装了对应版本的JDK和MySQL。第二种是用Docker编写Dockerfile和docker-compose.yml把MySQL、Redis、后端应用服务一起编排。这样演示环境可以一键起停稳定复现但增加了学习成本。我的判断是如果你的毕设时间还算充裕Docker部署一定要写进文档里因为现在很多评委都会问“你的项目怎么部署的”。你的回答是“用Docker Compose编排了MySQL、Redis和应用容器”这个技术栈层次会明显高于只说“本地运行”的同学。不过核心项目开发时间紧的话本地jar包启动也完全够用毕竟毕业设计的本质是考察你对业务和代码的理解不是考验运维水平。4.4 数据初始化与演示数据另一个容易被忽视的点系统里一定要有充足的演示数据。很多人交上去的系统点开图书列表只有两条手动录入的数据借阅排行统计半小时做不出效果答辩现场特别局促。我建议用Java的CommandLineRunner或写一个SQL脚本在系统启动时自动插入200本图书、50个读者、300条随机借阅记录。数据量一上来图表的展示效果、列表的分页效果、检索的筛选效果全都出来了。生成随机数据时注意一个细节借阅记录的借书时间要分布在不同月份不然“按月份统计借阅趋势”的图表就只有一个月有数据很难看。用Java的Random生成日期时把基准时间设为过去12个月内就可以让折线图非常平滑自然。5. 高频坑位与答辩实战经验5.1 从Debug到上线最折磨人的几个坑第一个坑是数据库连接配置里的时区问题。MySQL连接串中必须加serverTimezoneAsia/Shanghai和useSSLfalse不然启动直接报日期转换错误。第二个坑是BCrypt密码生成时机。很多同学直接在数据库里手动插入一条INSERT INTO reader ...密码字段却写的是明文123456结果登录永远提示密码错误。因为BCryptPasswordEncoder.matches()拿明文去和密文比对肯定失败。解决方法是写一个配置类启动时检查管理员的密码是不是BCrypt格式不是就自动加密。第三个坑是Lombok的使用。用了Data却忘了引入Lombok插件时IDEA里代码不报错但编译期会报“找不到符号getXxx”。这个问题每年都有大把人栽进去。还有EqualsAndHashCode(callSuper true)在子类继承BaseEntity时如果不加会导致两个不同记录被判定为相等后果就是更新一条记录时把另一条也更新了。第四个坑是我特别提示的不要在Controller里写业务逻辑。我见过很多人的Controller方法里直接new对象、直接调Mapper完全没有Service层。一开始可能觉得代码少了好办事但当借阅记录、馆藏副本、读者状态三个东西同时要改时没有Service层的事务管理系统基本处于“裸奔”状态。任何稍微复杂一点的需求都无从下手。5.2 答辩评委最常追问的10个问题这10个问题是我根据多年答辩现场整理出来的覆盖了图书管理系统最容易出彩也最容易翻车的角度为什么选SpringBoot它和Spring MVC有什么区别答案要点SpringBoot是Spring的快速开发脚手架内嵌Tomcat、自动装配、简化配置Spring MVC是Spring的Web框架模块。BCrypt是什么为什么不用MD5答案要点BCrypt自带盐值抗彩虹表攻击MD5不是加密算法而是哈希算法且可被暴力破解。你处理并发借书的方案是什么答案要点乐观锁或数据库原子更新控制单个副本状态唯一流转。如果同一本书所有副本都被借走你的系统怎么处理答案要点提到预约功能以及前端“不可借”状态的展示逻辑。借阅超期怎么算答案要点按自然日计算不做工作日排除具体计算公式在Service层。JWT和传统Session有什么不同答案要点JWT无状态、适合分布式、服务端不存储会话Session存储于服务端内存扩展时需考虑会话同步。数据库表为什么拆这么细答案要点图书和馆藏副本一对多满足各种状态追踪借阅记录冗余书名/图书ID是为了统计性能。Redis在你的项目里做什么答案要点验证码存储和刷新Token的黑名单属于缓存层与数据辅助层。你的项目如何做权限控制答案要点Spring Security JWT PreAuthorize角色注解。系统上线后如果MySQL性能遇到瓶颈怎么办答案要点可以从索引优化、分库分表、引入ES做全文检索、引入消息队列做削峰等方向展开。这个问题量力而行说清楚一到两个方向就好。5.3 项目包装与文档撰写建议毕设文档也是评分的重要一环。我建议在系统设计章节务必画一张完整的架构图表明前端Vue、后端SpringBoot、数据库MySQL、缓存Redis、接口文档Swagger的分层关系。数据库设计章节里每一张表必须配一个ER图并用文字说明为什么要冗余字段、为什么加索引。在“系统测试”这一章除了常规的“验证功能正常”要加入一个清晰亮眼的设计并发场景下的测试结果。比如写一个测试程序同时发起20个借阅请求针对同一本副本最终结果是只有1个请求成功其余19个都返回“借阅失败请稍后重试”。把这个结果截图放进文档比写一千字的“系统稳定性强”都有说服力。我在实际做这套系统的过程中最大的体感是图书管理系统本质上是一个“一切围绕状态流转设计”的业务系统。你理解了一本书从入馆到借出、归还、续借、预约的完整生命周期代码自然写得顺。反之如果只是背代码越做越乱。最后再分享一个小技巧项目完成后花半天时间把核心的50行代码重新手写一遍然后用自己的话把流程讲出来。这一招比看十遍代码都管用因为答辩本质是“讲”出来的不是“看”出来的。对自己写的东西足够熟悉在任何追问面前都不会慌。
返回列表