基于Spring Boot的图书管理系统毕设实战指南!从需求到测试全流程详解✨

92 阅读9分钟

基于Spring Boot的图书管理系统毕设实战指南!从需求到测试全流程详解✨

谁懂啊!去年做图书管理系统毕设时,光借阅归还和图书库存的关联就卡了4天——一开始没处理"借阅超期"逻辑,用户借书超期后系统没提醒,导师演示时直接发现了这个业务漏洞😫 经过反复修改优化,终于总结出了这套图书管理系统毕设实战经验,今天就把全流程细节分享给大家!

一、需求分析:抓住图书管理核心业务

刚开始我想做一个"万能图书馆系统",包含了读者管理、图书采购、财务统计等模块,结果导师说"重点不突出,核心借阅流程不清晰"。后来明白,图书管理系统要围绕图书-借阅-归还这个核心业务流程展开。

1. 核心用户角色与功能

系统主要面向两类用户,功能定位要精准:

  • 管理员端(系统管理核心):

    • 用户信息管理:维护读者信息、办理借阅证、重置密码
    • 图书信息管理:录入图书信息、设置图书分类、管理图书库存
    • 借阅信息管理:处理借阅申请、管理归还记录、计算超期费用
    • 系统基础管理:管理图书分类、出版社、书架位置等基础数据
    • 公告论坛管理:发布图书馆公告、管理读者交流论坛
  • 用户端(读者服务核心):

    • 图书查询:按条件检索图书、查看图书详情
    • 借阅管理:查看个人借阅记录、续借图书
    • 个人信息:维护个人资料、修改登录密码
    • 论坛交流:在图书馆论坛发帖交流

2. 需求分析实战技巧

  • 实地调研很重要:我去学校图书馆观察了真实的借阅流程,发现他们最需要"借阅超期提醒"功能,于是重点设计了借阅状态管理
  • 绘制业务流程图:用DrawIO画出"读者查询→借阅图书→归还图书"的完整流程,答辩时清晰展示业务逻辑
  • 明确业务规则:如"同一读者最多借5本书""借阅期限30天""超期每天罚款0.1元"等约束条件

3. 可行性分析要点

  • 技术可行性:Spring Boot+MySQL技术成熟,SSM框架资料丰富
  • 经济可行性:全部使用开源工具,零开发成本
  • 操作可行性:界面设计参考主流图书馆系统,读者上手快

二、技术选型:稳定可靠的开发架构

曾经尝试用微服务架构,结果服务调用配置卡了2天,最终选择单体架构,开发效率大大提升!

1. 技术栈选择理由

技术组件选择理由避坑提醒
Spring Boot 2.7配置简单,快速开发不要用3.x,兼容性问题多
MySQL 8.0数据关系明确,适合图书管理系统记得配置时区和字符集
SSM框架技术成熟,资料丰富注意MyBatis配置
Bootstrap 3.x兼容性好,开发快速不要用4.x,样式问题多

2. 开发环境搭建

# 创建Spring Boot项目
使用Spring Initializr
选择Web、MySQL、MyBatis依赖

# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/library_db?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456

三、数据库设计:图书业务数据建模

最初设计时把图书信息和借阅记录放在同一张表,导致数据冗余严重。重新设计后按业务模块分表,系统性能大幅提升。

1. 核心数据表设计

借阅信息表(tushujieyue)

CREATE TABLE `tushujieyue` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tushu_id` int(11) DEFAULT NULL COMMENT '图书ID',
  `yonghu_id` int(11) DEFAULT NULL COMMENT '用户ID',
  `tushujieyue_shijian` int(11) DEFAULT '30' COMMENT '借阅时间(天)',
  `tushujieyue_types` int(11) DEFAULT '0' COMMENT '借阅状态:0借阅中/1已归还',
  `jieyue_time` datetime DEFAULT NULL COMMENT '借阅时间',
  `guihuan_time` datetime DEFAULT NULL COMMENT '应归还时间',
  `shijiguihuan_time` datetime DEFAULT NULL COMMENT '实际归还时间',
  `chaogi_fine` decimal(10,2) DEFAULT '0.00' COMMENT '超期罚款',
  `insert_time` datetime DEFAULT NULL COMMENT '记录时间',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `fk_tushu` (`tushu_id`),
  KEY `fk_yonghu` (`yonghu_id`),
  KEY `idx_guihuan` (`guihuan_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='借阅信息表';

图书信息表(tushu)

CREATE TABLE `tushu` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tushu_uuid_number` varchar(200) DEFAULT NULL COMMENT '图书编号',
  `tushu_name` varchar(200) DEFAULT NULL COMMENT '图书标题',
  `tushu_types` int(11) DEFAULT NULL COMMENT '图书类型',
  `tushu_photo` varchar(200) DEFAULT NULL COMMENT '图书封面',
  `tushu_zuozhe` varchar(100) DEFAULT NULL COMMENT '图书作者',
  `chubanshe_types` int(11) DEFAULT NULL COMMENT '图书出版社',
  `shujia_types` int(11) DEFAULT NULL COMMENT '所在书架',
  `tushu_number` int(11) DEFAULT '1' COMMENT '图书数量',
  `tushu_kucun` int(11) DEFAULT '1' COMMENT '图书库存',
  `tushu_content` text COMMENT '图书详情',
  `insert_time` datetime DEFAULT NULL COMMENT '发布时间',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tushu_number` (`tushu_uuid_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='图书信息表';

2. 表关系设计要点

  • 状态字段设计:借阅状态(借阅中/已归还)、图书状态(在馆/借出)
  • 库存管理:借阅时扣减库存,归还时恢复库存
  • 超期计算:自动计算应归还时间和超期罚款

四、核心功能实现与代码详解

1. 借阅管理模块(核心业务功能)

Service层实现:

@Service
public class TushujieyueServiceImpl implements TushujieyueService {
    
    @Autowired
    private TushujieyueMapper tushujieyueMapper;
    
    @Autowired
    private TushuMapper tushuMapper;

    @Override
    @Transactional
    public void jieyueTushu(Integer tushuId, Integer yonghuId) {
        // 1. 检查图书库存
        TushuEntity tushu = tushuMapper.selectById(tushuId);
        if (tushu.getTushuKucun() <= 0) {
            throw new RuntimeException("该图书库存不足,无法借阅");
        }
        
        // 2. 检查用户借阅数量
        Integer jieyueCount = tushujieyueMapper.selectCount(
            new EntityWrapper<TushujieyueEntity>()
                .eq("yonghu_id", yonghuId)
                .eq("tushujieyue_types", 0) // 借阅中的图书
        );
        if (jieyueCount >= 5) {
            throw new RuntimeException("您已借阅5本书,达到最大借阅数量");
        }
        
        // 3. 检查是否重复借阅同一本书
        Integer chongfuCount = tushujieyueMapper.selectCount(
            new EntityWrapper<TushujieyueEntity>()
                .eq("yonghu_id", yonghuId)
                .eq("tushu_id", tushuId)
                .eq("tushujieyue_types", 0)
        );
        if (chongfuCount > 0) {
            throw new RuntimeException("您已借阅该图书,请勿重复借阅");
        }
        
        // 4. 创建借阅记录
        TushujieyueEntity jieyue = new TushujieyueEntity();
        jieyue.setTushuId(tushuId);
        jieyue.setYonghuId(yonghuId);
        jieyue.setTushujieyueTypes(0); // 借阅中
        jieyue.setJieyueTime(new Date());
        
        // 计算应归还时间(30天后)
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, 30);
        jieyue.setGuihuanTime(calendar.getTime());
        
        tushujieyueMapper.insert(jieyue);
        
        // 5. 扣减图书库存
        tushu.setTushuKucun(tushu.getTushuKucun() - 1);
        tushuMapper.updateById(tushu);
    }

    @Override
    @Transactional
    public void guihuanTushu(Integer jieyueId) {
        TushujieyueEntity jieyue = tushujieyueMapper.selectById(jieyueId);
        if (jieyue == null) {
            throw new RuntimeException("借阅记录不存在");
        }
        
        // 更新借阅状态
        jieyue.setTushujieyueTypes(1); // 已归还
        jieyue.setShijiguihuanTime(new Date());
        
        // 计算超期罚款
        Date now = new Date();
        if (now.after(jieyue.getGuihuanTime())) {
            long days = (now.getTime() - jieyue.getGuihuanTime().getTime()) / (1000 * 60 * 60 * 24);
            BigDecimal fine = new BigDecimal(days).multiply(new BigDecimal("0.1"));
            jieyue.setChaogiFine(fine);
        }
        
        tushujieyueMapper.updateById(jieyue);
        
        // 恢复图书库存
        TushuEntity tushu = tushuMapper.selectById(jieyue.getTushuId());
        tushu.setTushuKucun(tushu.getTushuKucun() + 1);
        tushuMapper.updateById(tushu);
    }
}

Controller层:

@Controller
@RequestMapping("/user/jieyue")
public class UserJieyueController {
    
    @Autowired
    private TushujieyueService tushujieyueService;

    @PostMapping("/jieyue")
    public String jieyueTushu(Integer tushuId, HttpServletRequest request) {
        try {
            // 设置当前登录用户
            YonghuEntity user = (YonghuEntity) request.getSession().getAttribute("user");
            
            tushujieyueService.jieyueTushu(tushuId, user.getId());
            request.setAttribute("msg", "借阅成功");
        } catch (Exception e) {
            request.setAttribute("msg", "借阅失败:" + e.getMessage());
        }
        return "redirect:/user/tushu/list";
    }

    @PostMapping("/guihuan")
    public String guihuanTushu(Integer jieyueId, HttpServletRequest request) {
        try {
            tushujieyueService.guihuanTushu(jieyueId);
            request.setAttribute("msg", "归还成功");
        } catch (Exception e) {
            request.setAttribute("msg", "归还失败:" + e.getMessage());
        }
        return "redirect:/user/jieyue/list";
    }
}

2. 图书查询模块(用户端核心功能)

Service层实现:

@Service
public class TushuServiceImpl implements TushuService {
    
    @Autowired
    private TushuMapper tushuMapper;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<TushuEntity> page = new Page<>(
            Integer.parseInt(params.get("page").toString()),
            Integer.parseInt(params.get("limit").toString())
        );
        
        EntityWrapper<TushuEntity> ew = new EntityWrapper<>();
        
        // 图书名称模糊查询
        if (params.get("tushuName") != null) {
            ew.like("tushu_name", params.get("tushuName").toString());
        }
        
        // 图书类型筛选
        if (params.get("tushuTypes") != null) {
            ew.eq("tushu_types", params.get("tushuTypes"));
        }
        
        // 作者模糊查询
        if (params.get("zuozhe") != null) {
            ew.like("tushu_zuozhe", params.get("zuozhe").toString());
        }
        
        // 只显示有库存的图书
        ew.gt("tushu_kucun", 0);
        
        IPage<TushuEntity> result = tushuMapper.selectPage(page, ew);
        return new PageUtils(result);
    }

    @Override
    public List<TushuEntity> getRecommendTushu() {
        // 获取推荐图书(点击量高的图书)
        return tushuMapper.selectList(
            new EntityWrapper<TushuEntity>()
                .gt("tushu_kucun", 0)
                .orderBy("tushu_clicknum", false)
                .last("limit 8")
        );
    }
}

3. 借阅统计模块(管理员功能)

Service层实现:

@Service
public class TongjiServiceImpl implements TongjiService {
    
    @Autowired
    private TushujieyueMapper tushujieyueMapper;

    @Override
    public Map<String, Object> getJieyueTongji() {
        Map<String, Object> result = new HashMap<>();
        
        // 今日借阅数量
        Integer todayJieyue = tushujieyueMapper.selectCount(
            new EntityWrapper<TushujieyueEntity>()
                .eq("DATE(insert_time)", new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
        );
        
        // 当前借阅中数量
        Integer jieyuezhong = tushujieyueMapper.selectCount(
            new EntityWrapper<TushujieyueEntity>()
                .eq("tushujieyue_types", 0)
        );
        
        // 超期未还数量
        Integer chaogiWeihuan = tushujieyueMapper.selectCount(
            new EntityWrapper<TushujieyueEntity>()
                .eq("tushujieyue_types", 0)
                .lt("guihuan_time", new Date())
        );
        
        result.put("todayJieyue", todayJieyue);
        result.put("jieyuezhong", jieyuezhong);
        result.put("chaogiWeihuan", chaogiWeihuan);
        
        return result;
    }
}

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

五、系统测试:确保借阅流程可靠

曾经以为功能实现就完成了,结果测试时发现同一用户能无限借书,紧急加了借阅数量限制。

1. 功能测试用例

借阅流程测试:

测试场景操作步骤预期结果
图书库存为0用户借阅库存为0的图书提示"库存不足"
借阅数量超限用户借阅第6本书提示"达到最大借阅数量"
重复借阅用户借阅已借阅的图书提示"请勿重复借阅"
正常借阅用户借阅有库存的图书提示"借阅成功",库存减1

归还流程测试:

测试场景操作步骤预期结果
超期归还用户超期归还图书计算超期罚款,库存恢复
按时归还用户按时归还图书提示"归还成功",库存恢复

2. 数据一致性测试

  • 借阅与库存:借阅时库存减少,归还时库存恢复
  • 超期计算:自动计算应归还时间和超期天数
  • 状态同步:图书状态与借阅状态实时同步

六、部署与演示准备

1. 数据库初始化脚本

-- 插入测试数据
INSERT INTO `tushu` VALUES 
(1, 'TS001', 'Java编程思想', 1, '/images/tushu1.jpg', 'Bruce Eckel', 1, 1, 5, 5, 'Java经典图书...', NOW(), NOW()),
(2, 'TS002', 'Spring Boot实战', 1, '/images/tushu2.jpg', 'Craig Walls', 1, 1, 3, 3, 'Spring Boot实战指南...', NOW(), NOW());

INSERT INTO `yonghu` VALUES 
(1, 'user1', '123456', '张三', '/images/user1.jpg', 1, '13800138000', '110101199001011234', 'user1@qq.com', 0, NOW());

2. 演示流程设计

按照真实借阅流程演示:

  1. 用户注册登录→查询图书→借阅图书
  2. 管理员登录→管理图书信息→查看借阅统计
  3. 用户归还图书→系统计算超期费用

3. 答辩重点准备

  • 业务逻辑亮点:借阅数量控制、超期自动计算
  • 技术实现亮点:Spring事务管理、数据一致性保障
  • 系统特色:完整的借阅归还流程、智能统计功能

结语

基于Spring Boot的图书管理系统毕设成功的关键在于:抓住借阅业务核心,处理好库存同步,保证数据一致性。这套系统虽然业务逻辑相对复杂,但一旦掌握,无论是完成度还是技术含量都能得到导师认可。

记住:借阅库存同步、超期自动计算、借阅数量控制是三大得分点!需要完整源码、数据库脚本、部署文档的同学可以在评论区留言。

点赞收藏这篇指南,你的图书管理系统毕设一定能顺利通过! 📚✨