SpringBoot+Vue3+MyBatis请假系统开发实战
1. 项目概述基于SpringBootVue3MyBatis的请假系统架构设计这个学生网上请假系统采用前后端分离架构后端使用SpringBoot框架提供RESTful API服务前端基于Vue3构建响应式管理界面数据持久层采用MyBatis操作MySQL数据库。这种技术组合在2023年已成为企业级应用开发的主流选择尤其适合需要快速迭代的中小型管理系统开发。我在实际开发中发现这种架构有三大核心优势首先SpringBoot的自动配置特性大幅减少了XML配置工作量其次Vue3的Composition API让前端状态管理更清晰最后MyBatis的SQL灵活性非常适合需要复杂查询的业务场景。下面我将从技术实现角度详细解析这个系统的关键设计。2. 技术栈选型与核心组件解析2.1 后端技术栈深度配置SpringBoot 2.7.x版本作为基础框架配置时特别注意了几个关键点使用spring-boot-starter-web提供Web服务集成spring-boot-starter-aop实现操作日志记录通过spring-boot-starter-validation进行参数校验数据库连接池选用HikariCP在application.yml中的典型配置如下spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/leave_system?useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 hikari: maximum-pool-size: 20 minimum-idle: 52.2 前端工程化实践Vue3项目通过Vite构建主要依赖包括vue-router 4.x处理路由跳转pinia 2.x替代Vuex的状态管理element-plusUI组件库axiosHTTP请求库项目结构采用模块化组织/src /api - 接口定义 /components - 公共组件 /router - 路由配置 /stores - pinia状态 /views - 页面组件2.3 MyBatis的优化实践在mapper.xml文件中我们使用了动态SQL特性处理复杂查询条件select idselectLeaveList resultMapLeaveResult SELECT * FROM t_leave where if teststudentId ! null AND student_id #{studentId} /if if teststatus ! null AND status #{status} /if /where ORDER BY create_time DESC /select3. 核心业务模块实现3.1 请假流程状态机设计系统定义了五种请假状态public enum LeaveStatus { PENDING(0, 待审批), APPROVED(1, 已批准), REJECTED(2, 已拒绝), CANCELLED(3, 已取消), COMPLETED(4, 已完成); }状态转换规则通过状态模式实现public interface LeaveState { void handle(LeaveContext context); } public class ApprovedState implements LeaveState { Override public void handle(LeaveContext context) { if(context.getCurrentStatus() PENDING) { context.setStatus(APPROVED); // 发送通知等后续操作 } } }3.2 权限控制实现方案采用RBAC模型通过Spring Security实现Configuration EnableWebSecurity public class SecurityConfig { Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers(/admin/**).hasRole(ADMIN) .antMatchers(/teacher/**).hasAnyRole(TEACHER, ADMIN) .antMatchers(/student/**).hasRole(STUDENT) .anyRequest().authenticated() .and() .formLogin(); return http.build(); } }3.3 前后端数据交互规范定义统一响应体public class ResultT { private Integer code; private String msg; private T data; public static T ResultT success(T data) { return new Result(200, 成功, data); } }前端封装axios请求const service axios.create({ baseURL: import.meta.env.VITE_APP_BASE_API, timeout: 5000 }) service.interceptors.response.use( response { const res response.data if (res.code ! 200) { ElMessage.error(res.msg || Error) return Promise.reject(new Error(res.msg || Error)) } return res } )4. 数据库设计与优化4.1 核心表结构学生表设计示例CREATE TABLE t_student ( id bigint NOT NULL AUTO_INCREMENT, student_no varchar(20) NOT NULL COMMENT 学号, name varchar(50) NOT NULL COMMENT 姓名, class_id bigint NOT NULL COMMENT 班级ID, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY idx_student_no (student_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;请假申请表关键字段CREATE TABLE t_leave ( id bigint NOT NULL AUTO_INCREMENT, student_id bigint NOT NULL, type tinyint NOT NULL COMMENT 请假类型, reason varchar(500) NOT NULL, start_time datetime NOT NULL, end_time datetime NOT NULL, status tinyint NOT NULL DEFAULT 0, approver_id bigint DEFAULT NULL, approve_time datetime DEFAULT NULL, approve_remark varchar(200) DEFAULT NULL, PRIMARY KEY (id), KEY idx_student_id (student_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;4.2 查询性能优化对于高频查询的请假列表接口我们添加了复合索引ALTER TABLE t_leave ADD INDEX idx_query (student_id, status, create_time);在MyBatis中启用二级缓存settings setting namecacheEnabled valuetrue/ /settings mapper namespacecom.leave.mapper.LeaveMapper cache evictionLRU flushInterval60000 size512/ /mapper5. 典型问题排查与解决方案5.1 跨域问题处理开发环境配置Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(*) .allowedMethods(GET, POST, PUT, DELETE) .allowCredentials(true) .maxAge(3600); } }生产环境建议通过Nginx配置location /api { add_header Access-Control-Allow-Origin $http_origin; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE; add_header Access-Control-Allow-Headers Content-Type; proxy_pass http://backend; }5.2 日期时间处理统一使用Java 8时间APIJsonFormat(pattern yyyy-MM-dd HH:mm:ss) private LocalDateTime startTime; JsonFormat(pattern yyyy-MM-dd HH:mm:ss) private LocalDateTime endTime;前端moment.js处理import moment from moment const formatTime (time) { return moment(time).format(YYYY-MM-DD HH:mm:ss) }5.3 文件上传实现SpringBoot后端实现PostMapping(/upload) public ResultString upload(RequestParam(file) MultipartFile file) { String fileName UUID.randomUUID() file.getOriginalFilename(); Path path Paths.get(uploadDir, fileName); Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING); return Result.success(/uploads/ fileName); }Vue3前端组件template el-upload action/api/upload :on-successhandleSuccess el-button typeprimary点击上传/el-button /el-upload /template6. 部署与运维实践6.1 多环境配置使用SpringBoot的profile特性# application-dev.yml server: port: 8080 spring: datasource: url: jdbc:mysql://dev-db:3306/leave_system # application-prod.yml server: port: 80 spring: datasource: url: jdbc:mysql://prod-db:3306/leave_system启动时指定profilejava -jar leave-system.jar --spring.profiles.activeprod6.2 前端部署优化Vite生产构建配置export default defineConfig({ build: { rollupOptions: { output: { manualChunks: { vue: [vue, vue-router, pinia], element: [element-plus], utils: [axios, dayjs] } } } } })Nginx配置示例server { listen 80; server_name leave.example.com; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://localhost:8080; } }6.3 数据库备份策略使用mysqldump定时备份#!/bin/bash DATE$(date %Y%m%d) mysqldump -uroot -p123456 leave_system /backup/leave_${DATE}.sql find /backup -name *.sql -mtime 7 -exec rm {} \;设置crontab每天凌晨执行0 0 * * * /usr/local/bin/backup_leave.sh7. 扩展功能与二次开发建议7.1 微信小程序集成通过uni-app改造前端// 修改api请求基地址 const baseURL https://leave.example.com/miniapi // 使用微信登录 uni.login({ provider: weixin, success: function (res) { console.log(res.code) } })7.2 工作流引擎集成引入Activiti实现复杂审批流Autowired private RuntimeService runtimeService; public void startLeaveProcess(Long leaveId) { MapString, Object variables new HashMap(); variables.put(leaveId, leaveId); runtimeService.startProcessInstanceByKey(leaveApproval, variables); }7.3 数据统计与分析使用ECharts实现可视化script setup import * as echarts from echarts const initChart () { const chart echarts.init(document.getElementById(chart)) chart.setOption({ xAxis: { type: category, data: [一月, 二月] }, yAxis: { type: value }, series: [{ data: [10, 20], type: bar }] }) } /script后端统计接口示例GetMapping(/stats/leave) public ResultLeaveStatsVO getLeaveStats( RequestParam(required false) Integer year) { return Result.success(leaveService.getLeaveStats(year)); }8. 项目经验与最佳实践8.1 开发环境配置技巧使用Lombok减少样板代码Data Builder NoArgsConstructor AllArgsConstructor public class LeaveDTO { private Long id; private Integer type; }配置热部署提高效率dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-devtools/artifactId scoperuntime/scope optionaltrue/optional /dependency8.2 代码质量保障措施集成Checkstyle代码检查plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-checkstyle-plugin/artifactId version3.1.2/version executions execution phasevalidate/phase goals goalcheck/goal /goals /execution /executions /plugin使用JaCoCo生成测试覆盖率报告plugin groupIdorg.jacoco/groupId artifactIdjacoco-maven-plugin/artifactId version0.8.7/version executions execution goals goalprepare-agent/goal goalreport/goal /goals /execution /executions /plugin8.3 性能优化经验启用Gzip压缩server: compression: enabled: true mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json min-response-size: 1024前端路由懒加载const routes [ { path: /leave, component: () import(../views/leave/Index.vue) } ]MyBatis批量插入优化Insert(script INSERT INTO t_leave_audit (leave_id, operator, action) VALUES foreach collectionlist itemitem separator, (#{item.leaveId}, #{item.operator}, #{item.action}) /foreach /script) void batchInsertAudit(ListLeaveAudit audits);

相关新闻

Python图书馆座位预约系统开发实战

Python图书馆座位预约系统开发实战

1. 项目背景与核心价值图书馆座位资源紧张是高校普遍存在的痛点。每到考试周,学生们凌晨排队抢座位的场景屡见不鲜。我去年为某高校开发的这套Python座位预约系统,上线后使座位利用率提升40%,学生投诉率下降65%。这个全栈项目融合了Python后端…

2026/10/17 16:16:57 阅读更多 →
SpringBoot与Vue构建宠物领养平台的技术实践

SpringBoot与Vue构建宠物领养平台的技术实践

1. 项目概述:全流程宠物管理领养平台的设计初衷去年参与某动物保护组织的技术志愿活动时,我亲眼目睹了传统宠物领养流程的三大痛点:纸质档案易丢失、领养双方信息不对称、后续追踪完全依赖人工。这促使我着手开发这个基于SpringBoot和Vue的全…

2026/10/17 16:22:44 阅读更多 →
JavaScript性能优化实战:从原理到实践

JavaScript性能优化实战:从原理到实践

1. JavaScript性能优化实战解析最近在重构一个大型前端项目时,我深刻体会到性能优化的重要性。当页面加载时间从3秒降到1秒内,用户留存率直接提升了27%。这让我意识到,性能优化不是可选项,而是现代Web开发的必修课。JavaScript作为…

2026/10/16 16:30:14 阅读更多 →

最新新闻

一阶倒立摆平衡车仿真与GUI调参工具:从建模到源码全解析

一阶倒立摆平衡车仿真与GUI调参工具:从建模到源码全解析

先说个反直觉的结论:做平衡车,最花时间的不一定是焊板子和调实车,而是把一阶倒立摆模型在GUI里跑通。我见过太多人上来就调PID,参数改来改去,最后连车为什么一直朝一个方向冲都说不清楚——根子在于脑子里没有一个能复…

2026/10/18 8:13:12 阅读更多 →
C++ STL系统学习:容器选型、迭代器算法与高频坑位排查

C++ STL系统学习:容器选型、迭代器算法与高频坑位排查

如果你在C的学习路线上已经走过了语法、类与对象、模板这几关,那么标准模板库(STL)大概率是你下一步绕不开的内容。DAY 3.17 这个编号通常来自一套系统化的学习计划,把STL安排在模板之后、并发和方向进阶之前,这个位置…

2026/10/18 8:13:12 阅读更多 →
SpringBoot+Vue智能旅游行程规划系统实战:从CRUD到智能算法

SpringBoot+Vue智能旅游行程规划系统实战:从CRUD到智能算法

1. 从标题拆解出真正的需求:不是做CRUD,而是做"规划"打开需求文档或者任务书,写着"基于SpringBootVue的智能旅游行程规划系统",很多人第一反应是:这不就是一个景点管理订单管理的CRUD吗&#xff1…

2026/10/18 8:13:12 阅读更多 →
WPF LiveCharts 动态折线图实战:线程安全与实时刷新避坑指南

WPF LiveCharts 动态折线图实战:线程安全与实时刷新避坑指南

简介:本资源是面向WPF平台C#开发者的LiveCharts动态折线图实战示例,专为需要实现数据实时可视化、趋势监控或交互式图表功能的中初级开发者设计。压缩包内含67个文件,涵盖11个核心C#源码文件(如MainWindow.xaml.cs、App.xaml.cs&a…

2026/10/18 8:13:12 阅读更多 →
AI写公文如何避免“AI味”?文风建模+仿写智能体实战

AI写公文如何避免“AI味”?文风建模+仿写智能体实战

写公文这件事,大多数同事不是不会写,是架不住“每次都是新任务”。更尴尬的是,很多朋友已经开始用AI帮忙了,但写出来的东西要么是空话堆砌,要么一股“万能模板味”,领导一眼就皱眉。问题不在AI不够聪明&…

2026/10/18 8:13:12 阅读更多 →
从手工到自动:做 PPT 的 10 步改造记录

从手工到自动:做 PPT 的 10 步改造记录

## 背景在团队协作场景里,做 PPT 找模板排版到半夜是效率的主要损耗点。## 核心能力- 文本素材自动梳理大纲- 大纲支持二次编辑- 多套配色模板可选- 渲染16:9标准PPTX文件## 落地场景团队协作等场景都能直接搬进工作流,输入是散乱的原始材料,…

2026/10/18 8:12:12 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →