SpringBoot与若依框架实战:快速构建图书管理系统全流程指南
最近在帮朋友做一个图书管理的小项目,原本想从零开始搭建,但考虑到时间成本和功能完整性,最终选择了基于若依(RuoYi)这个优秀的开源后台管理系统进行二次开发。结合SpringBoot的快速开发能力,整个项目从环境搭建到核心功能上线,效率提升非常明显。今天就把这个“基于SpringBoot+若依的图书管理系统”的完整实战过程整理出来,内容涵盖环境准备、项目导入、数据库设计、代码生成、业务定制、前端调整以及部署上线全流程。无论你是想快速完成一个毕业设计,还是为企业内部搭建一个轻量级的管理系统,这套方案都能让你直接复用,少走很多弯路。
1. 项目背景与核心技术栈介绍
在开始动手之前,我们有必要了解一下为什么选择这个技术组合,以及它能解决什么问题。
1.1 为什么是 SpringBoot + 若依?
SpringBoot大家都很熟悉了,它极大地简化了 Spring 应用的初始搭建和开发过程,通过自动配置和起步依赖,让我们能快速构建独立、生产级的应用。对于图书管理系统这类典型的 Web 应用,SpringBoot 提供了完善的 Web、数据访问、安全等模块支持。
而若依(RuoYi)是一个基于 SpringBoot 的权限管理系统,它并非一个简单的脚手架,而是一个功能完备的后台管理框架。它已经内置了用户管理、角色权限、菜单管理、部门管理、操作日志、代码生成器等后台系统必备的核心模块。这意味着,我们不需要从零开始写用户登录、权限校验这些通用且繁琐的功能,可以直接在其强大的基础上,专注于图书管理这个核心业务的开发。
两者的结合优势:
- 快速启动:利用若依的现成框架,省去基础模块开发时间。
- 规范统一:若依提供了清晰的前后端分离架构和代码规范。
- 功能复用:直接使用其代码生成器,能一键生成单表的增删改查前后端代码。
- 易于扩展:基于 SpringBoot 和若依的模块化设计,新增业务功能非常方便。
1.2 图书管理系统核心功能规划
我们的目标是一个具备基础 CRUD 和简单业务流程的管理系统,主要功能模块包括:
- 权限管理:用户、角色、菜单权限(复用若依)。
- 图书信息管理:图书的增、删、改、查,包括书名、作者、ISBN、出版社、分类、库存数量、价格等字段。
- 图书分类管理:对图书进行分类(如计算机、文学、历史等)。
- 借阅管理:记录用户的借书、还书操作,包括借阅人、图书、借出时间、应还时间、实际归还时间、状态(借出/在库/超期)等。
- 读者管理:管理系统的使用者(读者)信息。
- 数据统计:简单的数据看板,如图书总量、借阅排行、库存预警等。
2. 环境准备与项目初始化
工欲善其事,必先利其器。我们先来准备好开发环境并获取若依的基础项目。
2.1 开发环境清单
请确保你的本地开发环境已安装以下软件,版本号以稳定为主,无需追求最新:
| 环境/工具 | 推荐版本 | 说明 |
|---|---|---|
| JDK | 1.8 或 11 | SpringBoot 2.x 对 JDK 8 兼容性最好。若依官方推荐 JDK 1.8。 |
| Maven | 3.6+ | 用于项目依赖管理和构建。 |
| MySQL | 5.7 或 8.0 | 项目主数据库。本文使用 MySQL 8.0。 |
| Redis | 5.0+ | 若依用其做缓存和会话管理。必须安装。 |
| IDE | IntelliJ IDEA | 社区版或旗舰版均可,对 SpringBoot 支持好。 |
| Node.js | 14+ | 运行前端项目所需。 |
| Git | 最新版 | 用于克隆项目代码。 |
2.2 获取若依前后端分离版本
若依提供了多种版本(单体、前后端分离、微服务)。我们选择最流行的前后端分离版本,后端是 SpringBoot,前端是 Vue3。
- 访问若依官方仓库:在 Gitee 或 GitHub 上搜索 “RuoYi-Vue”。
- 克隆后端项目:
git clone https://gitee.com/y_project/RuoYi-Vue.git - 克隆前端项目(可选,后续部署需要):
我们主要进行后端开发,前端项目用于界面展示和联调。git clone https://gitee.com/y_project/RuoYi-Vue-UI.git
2.3 导入项目与基础配置
- 使用 IDEA 打开后端项目:打开
RuoYi-Vue文件夹。 - 配置 Maven:确保 IDEA 使用了正确的 Maven 设置和仓库。
- 修改数据库配置:找到
ruoyi-admin模块下的配置文件/src/main/resources/application-druid.yml。
注意:这里连接的是若依的默认数据库# 数据源配置 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ry_vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: your_password # 改为你的MySQL密码ry_vue,我们需要先创建它。 - 创建数据库并初始化:
-- 登录MySQL后执行 CREATE DATABASE IF NOT EXISTS `ry_vue` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE `ry_vue`; -- 执行项目sql文件夹下的初始化脚本 -- 通常位于 /ruoyi-admin/src/main/resources/sql/ 目录下,有多个版本,选择对应的(如 quartz.sql, ry_2024xxxx.sql) -- 在MySQL客户端中 source 这些sql文件,或者用IDE的数据库工具导入。 - 配置 Redis:修改
application.yml中的 Redis 配置。# redis 配置 redis: # 地址 host: localhost # 端口,默认为6379 port: 6379 # 数据库索引 database: 0 # 密码 password: # 连接超时时间 timeout: 10s - 启动后端项目:找到
RuoYiApplication主类,直接运行。访问http://localhost:8080应该能看到后端 API 文档(Swagger)页面,说明启动成功。
3. 数据库设计与表结构创建
在若依的ry_vue数据库中,我们需要新增图书管理相关的表。
3.1 核心表结构设计
我们设计四张核心表:book_type(图书分类)、book_info(图书信息)、reader_info(读者信息)、book_borrow(借阅记录)。表之间通过外键关联。
-- 1. 图书分类表 CREATE TABLE `book_type` ( `type_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类ID', `type_name` varchar(100) NOT NULL COMMENT '分类名称', `order_num` int(4) DEFAULT '0' COMMENT '显示顺序', `status` char(1) DEFAULT '0' COMMENT '状态(0正常 1停用)', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_by` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `remark` varchar(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (`type_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='图书分类表'; -- 2. 图书信息表 CREATE TABLE `book_info` ( `book_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '图书ID', `book_name` varchar(200) NOT NULL COMMENT '图书名称', `author` varchar(100) DEFAULT NULL COMMENT '作者', `isbn` varchar(50) DEFAULT NULL COMMENT 'ISBN编号', `publisher` varchar(100) DEFAULT NULL COMMENT '出版社', `type_id` bigint(20) DEFAULT NULL COMMENT '分类ID', `price` decimal(10,2) DEFAULT NULL COMMENT '价格', `total_count` int(11) NOT NULL DEFAULT '0' COMMENT '总库存', `current_count` int(11) NOT NULL DEFAULT '0' COMMENT '当前可借库存', `location` varchar(200) DEFAULT NULL COMMENT '存放位置', `status` char(1) DEFAULT '0' COMMENT '状态(0在库 1借出 2维护)', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_by` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `remark` varchar(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (`book_id`), KEY `idx_type_id` (`type_id`), CONSTRAINT `fk_book_type` FOREIGN KEY (`type_id`) REFERENCES `book_type` (`type_id`) ON DELETE SET NULL ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='图书信息表'; -- 3. 读者信息表 (可以复用若依的 sys_user,这里为了清晰单独建表,实际可关联) CREATE TABLE `reader_info` ( `reader_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '读者ID', `reader_name` varchar(50) NOT NULL COMMENT '读者姓名', `gender` char(1) DEFAULT '0' COMMENT '性别(0男 1女 2未知)', `phone` varchar(11) DEFAULT NULL COMMENT '手机号码', `email` varchar(50) DEFAULT NULL COMMENT '邮箱', `id_card` varchar(18) DEFAULT NULL COMMENT '身份证号', `max_borrow` int(11) DEFAULT '5' COMMENT '最大可借数量', `status` char(1) DEFAULT '0' COMMENT '状态(0正常 1锁定)', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_by` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `remark` varchar(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (`reader_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='读者信息表'; -- 4. 图书借阅记录表 CREATE TABLE `book_borrow` ( `borrow_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '借阅ID', `reader_id` bigint(20) NOT NULL COMMENT '读者ID', `book_id` bigint(20) NOT NULL COMMENT '图书ID', `borrow_time` datetime NOT NULL COMMENT '借出时间', `due_time` datetime NOT NULL COMMENT '应还时间', `return_time` datetime DEFAULT NULL COMMENT '实际归还时间', `status` char(1) DEFAULT '0' COMMENT '状态(0借出中 1已归还 2超期未还)', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_by` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `remark` varchar(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (`borrow_id`), KEY `idx_reader_id` (`reader_id`), KEY `idx_book_id` (`book_id`), CONSTRAINT `fk_borrow_reader` FOREIGN KEY (`reader_id`) REFERENCES `reader_info` (`reader_id`), CONSTRAINT `fk_borrow_book` FOREIGN KEY (`book_id`) REFERENCES `book_info` (`book_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='图书借阅记录表';设计要点说明:
- 字段规范:遵循若依的字段命名习惯,如
create_by,create_time,update_by,update_time,status,remark,便于框架自动填充。 - 库存管理:
book_info表设计了total_count(总库存)和current_count(当前可借库存)。借书时current_count减1,还书时加1。 - 状态枚举:使用
char(1)存储状态,‘0’,‘1’,‘2’等代表不同状态,在代码中定义枚举类。 - 外键约束:虽然生产环境有时会避免使用数据库外键,但在学习和小型项目中,使用外键可以保证数据一致性。这里添加了外键约束。
4. 使用若依代码生成器快速构建CRUD
这是若依框架最强大的功能之一,能根据数据库表,一键生成包括实体类、Mapper、Service、Controller以及前端Vue页面在内的所有基础代码。
4.1 配置代码生成器
- 启动项目,使用默认账号
admin/ 密码admin123登录系统。 - 进入系统菜单:系统工具->代码生成。
- 导入需要生成的表:点击“导入”按钮,选择我们刚创建的四张表 (
book_type,book_info,reader_info,book_borrow)。 - 编辑每张表的生成信息:
- 基本信息:设置生成模块名(如
library)、业务名(如bookType)、类名(如BookType)、功能作者。 - 字段信息:检查并确认每个字段的 Java 属性名、类型(String, Integer, BigDecimal, Date等)以及是否在列表中显示、是否为查询条件、表单显示类型(输入框、下拉框、日期控件等)。
- 例如,
book_info表的type_id字段,在生成前端表单时,应设置为“下拉框”,并关联book_type表的数据。 status字段通常设置为“单选框”或“下拉框”,并配置字典值(如0=正常,1=停用)。
- 例如,
- 生成信息:配置生成模板(默认即可),设置前端路径(如
vue)和包路径(如com.ruoyi.library)。
- 基本信息:设置生成模块名(如
4.2 生成与导入代码
- 在每张表的编辑页面配置完成后,保存。
- 在代码生成主列表,勾选要生成的所有表,点击“生成代码”。
- 下载生成的代码压缩包并解压。
- 后端代码:将解压后的
java文件夹下的内容,复制到后端项目的对应包路径下(如com.ruoyi.library)。将resources文件夹下的mapper文件复制到项目的resources/mapper目录下。 - 前端代码:将解压后的
vue文件夹下的.vue文件,复制到前端项目的对应目录(通常是/src/views/下的模块文件夹,如library/bookType)。 - 重启后端服务:因为新增了
@RestController等组件,需要重启应用。 - 配置菜单权限:
- 进入若依后台:系统管理->菜单管理。
- 在合适的目录下(如可以新建一个“图书管理”目录),新建菜单。
- 菜单类型选择“菜单”,组件路径填写前端生成代码中
.vue文件的路径(如library/bookType/index)。 - 权限标识填写生成代码中 Controller 的请求映射前缀(如
library:bookType:list)。 - 为不同的角色(如管理员)分配这些新菜单的权限。
完成以上步骤后,刷新页面,你应该能在侧边栏看到“图书分类管理”、“图书信息管理”等菜单,并且已经具备了基础的列表查询、新增、修改、删除、导出功能。这就是若依代码生成器的威力!
5. 核心业务逻辑定制开发
代码生成器提供了骨架,但复杂的业务逻辑需要我们自己实现。以借书和还书功能为例。
5.1 借书业务逻辑实现
借书不是简单的插入一条book_borrow记录,它需要一系列业务校验和状态更新。
- 创建 Service 方法:在
BookBorrowService接口和其实现类BookBorrowServiceImpl中,新增一个借书方法。// BookBorrowService.java public interface BookBorrowService { // ... 其他生成的CRUD方法 /** * 借阅图书 * @param borrow 借阅信息 * @return 结果 */ AjaxResult borrowBook(BookBorrow borrow); }// BookBorrowServiceImpl.java @Service public class BookBorrowServiceImpl implements BookBorrowService { @Autowired private BookBorrowMapper bookBorrowMapper; @Autowired private BookInfoMapper bookInfoMapper; @Autowired private ReaderInfoMapper readerInfoMapper; @Override @Transactional(rollbackFor = Exception.class) // 重要!开启事务 public AjaxResult borrowBook(BookBorrow borrow) { // 1. 参数校验 if (borrow.getReaderId() == null || borrow.getBookId() == null) { return AjaxResult.error("读者或图书信息不能为空"); } // 2. 校验读者状态和可借数量 ReaderInfo reader = readerInfoMapper.selectReaderInfoById(borrow.getReaderId()); if (reader == null) { return AjaxResult.error("读者不存在"); } if ("1".equals(reader.getStatus())) { return AjaxResult.error("读者账户已被锁定,无法借书"); } // 查询该读者当前借出未还的数量 Long borrowingCount = bookBorrowMapper.countBorrowingByReaderId(borrow.getReaderId()); if (borrowingCount >= reader.getMaxBorrow()) { return AjaxResult.error("已达到最大可借阅数量"); } // 3. 校验图书库存和状态 BookInfo book = bookInfoMapper.selectBookInfoById(borrow.getBookId()); if (book == null) { return AjaxResult.error("图书不存在"); } if (book.getCurrentCount() <= 0) { return AjaxResult.error("该图书暂无库存"); } if (!"0".equals(book.getStatus())) { return AjaxResult.error("图书状态不可借阅"); } // 4. 更新图书库存和状态 book.setCurrentCount(book.getCurrentCount() - 1); if (book.getCurrentCount() == 0) { book.setStatus("1"); // 状态改为借出 } bookInfoMapper.updateBookInfo(book); // 5. 设置借阅记录信息 borrow.setBorrowTime(new Date()); // 借出时间 // 计算应还时间,例如30天后 Calendar calendar = Calendar.getInstance(); calendar.setTime(borrow.getBorrowTime()); calendar.add(Calendar.DAY_OF_MONTH, 30); borrow.setDueTime(calendar.getTime()); borrow.setStatus("0"); // 状态:借出中 // 若依框架会自动填充 createBy, createTime 等字段 // 6. 插入借阅记录 bookBorrowMapper.insertBookBorrow(borrow); return AjaxResult.success("借阅成功"); } } - 创建 Controller 接口:在
BookBorrowController中暴露借书API。@RestController @RequestMapping("/library/borrow") public class BookBorrowController extends BaseController { @Autowired private BookBorrowService bookBorrowService; @PostMapping("/borrowBook") public AjaxResult borrowBook(@RequestBody BookBorrow borrow) { return bookBorrowService.borrowBook(borrow); } } - 补充 Mapper 查询:需要在
BookBorrowMapper.xml中新增一个统计查询。<!-- 统计读者未归还的借阅数量 --> <select id="countBorrowingByReaderId" parameterType="Long" resultType="Long"> SELECT count(1) FROM book_borrow WHERE reader_id = #{readerId} AND status in ('0', '2') -- 借出中或超期未还 </select>
5.2 还书业务逻辑实现
还书逻辑同样需要更新图书状态和借阅记录状态。
// BookBorrowServiceImpl.java 中新增方法 @Override @Transactional(rollbackFor = Exception.class) public AjaxResult returnBook(Long borrowId) { // 1. 查询借阅记录 BookBorrow borrow = bookBorrowMapper.selectBookBorrowById(borrowId); if (borrow == null) { return AjaxResult.error("借阅记录不存在"); } if (!"0".equals(borrow.getStatus())) { return AjaxResult.error("该图书已归还或状态异常"); } // 2. 查询对应图书 BookInfo book = bookInfoMapper.selectBookInfoById(borrow.getBookId()); if (book == null) { return AjaxResult.error("对应图书不存在"); } // 3. 更新图书库存和状态 book.setCurrentCount(book.getCurrentCount() + 1); // 如果当前库存从0变为1,状态改回在库 if (book.getCurrentCount() == 1) { book.setStatus("0"); } bookInfoMapper.updateBookInfo(book); // 4. 更新借阅记录 borrow.setReturnTime(new Date()); // 实际归还时间 // 判断是否超期 if (borrow.getReturnTime().after(borrow.getDueTime())) { borrow.setStatus("2"); // 超期归还 (可根据需要记录罚金等) } else { borrow.setStatus("1"); // 正常归还 } bookBorrowMapper.updateBookBorrow(borrow); return AjaxResult.success("归还成功"); }5.3 前端页面调用后端API
在前端生成的bookBorrow.vue页面中,我们需要添加“借书”和“还书”的按钮和对话框。
- 在列表操作列添加“还书”按钮(仅当状态为“借出中”时显示)。
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <template slot-scope="scope"> <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['library:borrow:edit']" >修改</el-button> <!-- 还书按钮 --> <el-button size="mini" type="text" icon="el-icon-circle-check" @click="handleReturn(scope.row)" v-hasPermi="['library:borrow:return']" v-if="scope.row.status === '0'" <!-- 状态为借出中 --> >还书</el-button> </template> </el-table-column> - 在 methods 中实现
handleReturn方法。// 还书操作 handleReturn(row) { this.$modal.confirm('确认归还图书《' + row.bookName + '》吗?').then(() => { returnBook(row.borrowId).then(response => { this.$modal.msgSuccess("归还成功"); this.getList(); // 刷新列表 }); }).catch(() => {}); }, - 在
api文件夹下的bookBorrow.js中新增returnBook函数。// 还书 export function returnBook(borrowId) { return request({ url: '/library/borrow/returnBook/' + borrowId, method: 'post' }) } - 同理,可以创建一个独立的“借书”页面或对话框,调用我们写的
borrowBookAPI。
6. 常见问题与排查思路(FAQ)
在开发过程中,你可能会遇到以下典型问题,这里提供排查思路。
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 代码生成后,菜单不显示或页面404 | 1. 菜单组件路径配置错误。 2. 前端路由未注册。 3. 权限未分配。 | 1. 检查菜单管理中的“组件路径”是否与前端.vue文件路径一致。2. 在前端项目的路由文件(如 router/index.js)中,检查是否自动或手动添加了该模块的路由。3. 检查角色管理,是否为当前登录角色分配了该菜单权限。 |
| 若依框架启动报错,连接数据库/Redis失败 | 1. 数据库/Redis服务未启动。 2. application.yml配置错误。3. 驱动包版本不匹配。 | 1. 用命令行或工具确认 MySQL 和 Redis 服务是否正常运行。 2. 仔细核对 application-druid.yml和application.yml中的连接信息(主机、端口、密码、数据库名)。3. 检查 pom.xml中 MySQL Connector 和 Redis 客户端的版本。 |
| 前端调用后端API报404 | 1. 后端 Controller 请求路径 (@RequestMapping) 与前端请求 URL 不匹配。2. 后端服务未重启,新增的 Controller 未加载。 3. 跨域问题(开发环境常见)。 | 1. 对比浏览器开发者工具 Network 中的请求 URL 和后端 Controller 类的路径。 2. 重启后端 SpringBoot 应用。 3. 若依已配置跨域,检查配置是否被覆盖。开发时也可暂时关闭浏览器安全策略测试。 |
插入或更新数据时,create_by等字段为null | 若依的自动填充功能未生效。 | 确保你的实体类继承了BaseEntity,并且字段名与基类中定义的一致。检查application.yml中是否配置了mybatis-plus的全局填充策略。 |
| 使用代码生成器时,下拉框数据不显示 | 未配置字典数据或关联表查询。 | 1. 对于固定枚举(如状态),在系统管理的“字典管理”中创建字典类型和字典数据,然后在代码生成器字段配置中选择该字典。 2. 对于关联表(如图书分类),需要在生成后,手动修改前端组件,使用 select组件并调用分类查询接口获取数据。 |
| 打包成Jar后运行报错,提示找不到主清单 | Maven 打包插件配置问题。 | 在父工程或ruoyi-admin模块的pom.xml中,确保有spring-boot-maven-plugin插件,并且指定了mainClass。若依原项目已配置,检查是否被修改。 |
7. 项目优化与生产部署建议
完成基础功能后,可以考虑以下优化点,让系统更健壮、更专业。
7.1 后端优化建议
- 接口幂等性:对于借书、还书这类重要操作,考虑使用唯一业务流水号或Token机制防止重复提交。
- 数据校验:在 Controller 层使用
@Validated注解配合 JSR-303 校验注解(如@NotNull,@Size)对入参进行校验。 - 全局异常处理:若依已有
GlobalExceptionHandler,可以在此统一处理业务异常,返回友好的错误信息。 - 分页优化:对于大数据量的表(如借阅记录),确保分页查询使用索引,避免深分页问题。
- 缓存应用:将不常变动的数据(如图书分类)放入 Redis 缓存,减少数据库压力。
- 定时任务:使用若依集成的 Quartz 或 Spring Task,创建定时任务,每天检查超期未还的借阅记录,并更新状态或发送提醒。
7.2 前端优化建议
- 表单验证:充分利用 Element UI 的表单验证规则,在前端进行初步校验。
- 按钮防抖:给提交按钮添加
loading状态或防抖处理,防止用户连续点击。 - 数据字典:将状态等枚举值在前端也定义为常量或从字典接口获取,避免硬编码。
- 组件复用:将通用的组件(如图书选择器、读者选择器)抽离出来,提高代码复用率。
7.3 部署上线
- 后端打包:在项目根目录执行
mvn clean package -DskipTests,在ruoyi-admin/target目录下生成可执行的jar文件。 - 前端构建:进入前端项目目录,执行
npm run build:prod,生成静态资源文件在dist文件夹。 - 环境配置:准备生产环境的
application-prod.yml,配置生产数据库、Redis地址、日志路径等。 - 部署方式:
- 传统部署:将
jar包和前端dist文件夹放到服务器。使用 Nginx 代理前端请求到dist,反向代理 API 请求到后端jar应用(默认端口8080)。使用nohup或 systemd 守护进程运行jar包。 - Docker 部署(推荐):编写
Dockerfile和docker-compose.yml,将 MySQL、Redis、后端应用、Nginx 容器化部署,管理更方便。这也是当前热门的部署方式。
- 传统部署:将
- 安全加固:修改默认密码,检查若依的安全配置(如 XSS过滤、SQL防注入),关闭不必要的接口(如Swagger在生产环境应禁用)。
通过以上步骤,一个功能相对完整、架构清晰的基于 SpringBoot 和若依的图书管理系统就搭建完成了。这个项目不仅实现了业务功能,更重要的是展示了如何在一个成熟的开源框架上进行高效的二次开发。你可以在此基础上继续扩展,比如加入扫码借书、数据报表分析、微信小程序端等,使其成为一个更强大的综合管理系统。
