2026/9/16 3:39:09

SpringBoot 2.7养老平台实战:数据库调优与Vue实时交互

SpringBoot 2.7养老平台实战:数据库调优与Vue实时交互 简介本资源是一套面向高校计算机专业本科生的毕业设计完整交付包聚焦社区养老信息化服务场景助力学生快速完成SpringBootVue全栈开发类毕设课题。系统采用前后端分离架构后端基于JavaSpringBoot开发前端使用Vue.js构建响应式界面MySQL负责数据持久化覆盖用户管理、服务预约、订单审核、留言互动等核心业务模块。压缩包共380个文件含90个Java后端逻辑文件、36个Vue组件与页面、22张JPG/JPEG运营图、3个MP4演示视频及SQL建库脚本等整体19.02MB结构清晰便于二次开发与功能拆解。目前已有127人学习下载资源包含可直接运行的源码、配套数据库、完整毕业论文文档及全流程操作演示视频特别适合毕设时间紧张、需快速搭建原型并理解养老服务平台业务闭环的学生参考复用。1. 社区养老服务平台不是“管理后台”而是连接老人、家属、护理员与社区资源的实时服务中枢很多同学把毕业设计里的“社区养老服务平台”默认做成一个带登录的 CRUD 后台系统管理员增删改查老人信息、录入护理计划、导出 Excel 报表。但真实场景中它必须解决三类高频冲突家属在微信里反复追问“张阿姨今天吃药了吗”护理员手写纸质巡检表导致数据延迟 8 小时以上社区活动室空置率超 60% 却没人知道可预约。这个 SpringBoot Vue MySQL 组合不是技术堆砌而是用最小可行架构承载「服务可追溯、状态可感知、响应可闭环」的核心逻辑——SpringBoot 提供稳定的服务接口与事务边界Vue 实现家属端实时消息提醒与服务确认弹窗MySQL 则通过合理索引支撑“近 7 天所有失能老人用药记录查询”这类业务 SQL 在 200ms 内返回。适合正在做毕设、需要交付可演示、可答辩、可跑通全流程含视频演示的计算机/软件工程专业学生尤其适合对“如何让数据库不拖慢前端加载”“Vue 打包后路由刷新 404 怎么解”“SpringBoot 连接池参数调多少才不爆 timeout”有具体困惑的人。2. 用 SpringBoot 2.7.x 搭建高可用服务层从依赖选择到数据库连接池调优2.1 为什么选 SpringBoot 2.7.x 而非 3.x兼容性与毕业答辩稳定性优先SpringBoot 3.x 强制要求 JDK 17 且默认启用 Jakarta EE 9而多数高校机房、答辩演示电脑仍为 JDK 8 或 11 环境同时主流国产数据库驱动如达梦、人大金仓对 Jakarta EE 9 的适配尚未完全覆盖。SpringBoot 2.7.x 是最后一个支持 Servlet 4.0 Java EE 8 的稳定分支其spring-boot-starter-web、spring-boot-starter-data-jpa与 MySQL 8.0 驱动mysql-connector-java:8.0.33组合经实测可在 Windows 10/11、Ubuntu 20.04、macOS Monterey 下零报错启动。关键依赖配置如下!-- pom.xml -- properties java.version11/java.version spring-boot.version2.7.18/spring-boot.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId version${spring-boot.version}/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId version${spring-boot.version}/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version scoperuntime/scope /dependency /dependencies提示不要使用mysql-connector-j新版命名它在 SpringBoot 2.7.x 中存在Driver not found异常务必保留scoperuntime/scope否则编译期会误报 JDBC 类缺失。2.2 application.yml 中的 5 个必调数据库参数让 MySQL 不在高并发演示时卡死毕业答辩现场常出现“点击‘今日巡检’按钮后页面转圈 10 秒”的问题根源往往不在 SQL 本身而在连接池配置。以下参数基于 HikariCPSpringBoot 2.7 默认连接池实测优化适用于本地 MySQL 8.0 单实例部署参数名推荐值说明spring.datasource.hikari.maximum-pool-size12毕设演示最大并发约 20 请求12 连接足够设过高如 30会导致 MySQLmax_connections超限默认 151spring.datasource.hikari.minimum-idle4保底空闲连接数避免冷启动后首次请求等待连接创建spring.datasource.hikari.connection-timeout3000单位毫秒超时即报错而非无限等待防止前端假死spring.datasource.hikari.idle-timeout60000010 分钟空闲连接回收阈值避免长连接占用 MySQL 线程spring.datasource.hikari.max-lifetime180000030 分钟强制连接重建规避 MySQLwait_timeout默认 28800 秒导致的Connection reset完整配置段落# application.yml spring: datasource: url: jdbc:mysql://localhost:3306/community_care?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrueuseSSLfalse username: root password: 123456 hikari: maximum-pool-size: 12 minimum-idle: 4 connection-timeout: 3000 idle-timeout: 600000 max-lifetime: 1800000 jpa: hibernate: ddl-auto: update # 仅开发阶段用答辩前务必改为 validate show-sql: false properties: hibernate: format_sql: true注意ddl-auto: update在答辩前必须改为validate否则演示时可能因实体类字段变更意外清空测试数据show-sql: false是硬性要求开启后日志刷屏会导致 IDEA 控制台卡顿影响答辩流畅度。2.3 养老核心业务表设计用复合索引加速“老人-服务-时间”三重查询社区养老平台最常被问及的演示操作是“查李奶奶近 3 天所有上门护理记录”。该查询需关联elderly老人、care_service服务类型、service_record服务记录三张表并按时间倒序。若无索引1000 条记录下查询耗时可达 1.2 秒。正确建表语句如下含注释说明索引逻辑-- 老人基础信息表 CREATE TABLE elderly ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, phone VARCHAR(20), level TINYINT COMMENT 失能等级0-正常,1-轻度,2-中度,3-重度, community_id BIGINT NOT NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 服务记录主表重点联合索引覆盖查询条件 CREATE TABLE service_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, elderly_id BIGINT NOT NULL, service_type_id TINYINT NOT NULL, status TINYINT COMMENT 0-待执行,1-已完成,2-已取消, exec_time DATETIME NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_elderly_time_status (elderly_id, exec_time, status) -- 覆盖 WHERE elderly_id? AND exec_time? AND status1 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 服务类型字典表轻量级无需索引 CREATE TABLE service_type ( id TINYINT PRIMARY KEY, name VARCHAR(30) NOT NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;对应 JPA Repository 查询方法// ServiceRecordRepository.java public interface ServiceRecordRepository extends JpaRepositoryServiceRecord, Long { // 自动匹配 idx_elderly_time_status 索引 ListServiceRecord findByElderlyIdAndExecTimeAfterAndStatus( Long elderlyId, LocalDateTime startTime, Integer status ); }提示exec_time字段必须用DATETIME类型非TIMESTAMP因后者受 MySQL 时区设置影响演示时若服务器时区为 UTC会导致“查今日记录”实际查成昨日startTime参数传入LocalDateTime.now().minusDays(3)即可JPA 自动转换。3. Vue 3 Composition API 构建家属端解决打包后路由 404 与视频播放兼容性3.1 Vue Router 4 的 history 模式失效用 Nginx 配置兜底而非降级为 hash 模式毕设演示视频常被要求“打开首页直接显示 /elderly/list不要带 # 号”。Vue Router 4 默认history模式在npm run build后若直接双击index.html打开会因浏览器同源策略报 404而改成hash模式/#/elderly/list虽能运行但答辩时会被质疑“不符合现代 Web 规范”。正确解法是在本地用 Nginx 代理而非直接打开 HTML 文件。Nginx 配置如下nginx.confserver { listen 8081; server_name localhost; root /path/to/your/dist; # 替换为你的 vue 打包输出目录 index index.html; location / { try_files $uri $uri/ /index.html; # 关键所有路径都 fallback 到 index.html } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control public, immutable; } }启动命令nginx -c /path/to/nginx.conf然后浏览器访问http://localhost:8081即可。此方案无需修改 Vue 代码且符合企业级部署惯例。3.2 家属端视频播放用原生 video 标签替代第三方库兼容 M3U8 流媒体标题中“vue播放m3u8”是高频热词但毕设无需实现直播推流只需播放护理员上传的.m3u8回放视频如“张阿姨今日服药过程”。强行引入hls.js会增加打包体积且在 IE11 下报错。实测方案仅对 Chrome/Edge/Firefox 使用原生videoSafari 用hls.js按需加载。关键代码!-- VideoPlayer.vue -- template div classvideo-container video refvideoRef :srcvideoUrl controls preloadmetadata errorhandleVideoError / div v-ifisHlsNeeded classhls-tip正在加载视频请稍候.../div /div /template script setup import { ref, onMounted, onUnmounted } from vue const props defineProps({ videoUrl: { type: String, required: true } }) const videoRef ref(null) const isHlsNeeded ref(false) // 检测是否为 Safari需 hls.js const isSafari /Safari/.test(navigator.userAgent) /Apple Computer/.test(navigator.vendor) onMounted(() { if (isSafari props.videoUrl.endsWith(.m3u8)) { isHlsNeeded.value true // 动态导入 hls.js仅 Safari 需要 import(hls.js).then(Hls { if (Hls.isSupported()) { const hls new Hls() hls.loadSource(props.videoUrl) hls.attachMedia(videoRef.value) hls.on(Hls.Events.MANIFEST_PARSED, () { videoRef.value.play() }) } }) } }) const handleVideoError () { console.error(Video load failed:, props.videoUrl) // 此处可触发 Toast 提示“视频暂不可用” } /script注意preloadmetadata是关键它让浏览器只加载视频元数据时长、分辨率而非全部内容避免家属端首次打开页面时卡顿error事件必须监听否则.mp4视频路径错误时页面静默失败答辩时无法定位问题。3.3 家属确认服务完成用 WebSocket 实现实时状态同步避免轮询家属在手机端点击“确认李奶奶已服药”后护理员 App 应立刻看到状态变更为“已确认”而非等 30 秒轮询刷新。SpringBoot 端启用 WebSocketSTOMP 协议Vue 端用stomp/stompjs连接// WebSocketConfig.java Configuration EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker(/topic); // 订阅地址前缀 config.setApplicationDestinationPrefixes(/app); // 发送地址前缀 } }Vue 端发送确认// 在确认按钮 click 事件中 import { Client } from stomp/stompjs const client new Client({ brokerURL: ws://localhost:8080/ws, connectHeaders: { login: user, passcode: pass }, debug: str console.log(str) }) client.onConnect () { client.publish({ destination: /app/service/confirm, body: JSON.stringify({ recordId: 123, confirmedBy: 家属-张伟 }) }) } client.activate() // 建立连接后端接收并广播// ServiceController.java MessageMapping(/service/confirm) SendTo(/topic/service/status) public ServiceStatus confirmService(ConfirmRequest request) { // 更新数据库状态 serviceRecordService.confirm(request.getRecordId(), request.getConfirmedBy()); // 返回新状态供前端更新 return new ServiceStatus(request.getRecordId(), 已确认, new Date()); }提示WebSocket 连接地址ws://localhost:8080/ws必须与 SpringBoot 的server.port8080一致若 Vue 前端跑在http://localhost:8081需在 SpringBoot 中添加跨域配置CrossOrigin(origins http://localhost:8081)否则握手失败。4. 数据库初始化与演示脚本一键导入 50 条真实感测试数据4.1 用 Flyway 实现数据库版本控制告别手动执行 SQL 文件答辩时若被问“如何保证 10 台演示机的数据库结构完全一致”回答“我有个 sql 文件大家自己执行”显然不够专业。Flyway 是 SpringBoot 官方推荐的数据库迁移工具它将 SQL 脚本按版本号自动执行确保每次mvn spring-boot:run启动时数据库结构与代码完全同步。配置步骤添加依赖dependency groupIdorg.flywaydb/groupId artifactIdflyway-core/artifactId /dependency在src/main/resources/db/migration下创建 V1__init.sql-- V1__init.sql CREATE TABLE community ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, address VARCHAR(200) ); INSERT INTO community VALUES (1, 阳光花园社区, 北京市朝阳区建国路88号), (2, 梧桐苑社区, 上海市浦东新区世纪大道1001号);application.yml中启用spring: flyway: enabled: true locations: classpath:db/migration baseline-on-migrate: true # 首次运行时自动建 baseline 表启动后Flyway 会自动创建flyway_schema_history表并执行 V1__init.sql后续新增 V2__add_elderly_table.sql 等版本号严格递增。4.2 生成 50 条带真实感的老人数据用 Python 脚本避免手工造数据手动填 50 条老人信息姓名、电话、失能等级、所在社区极其耗时且易出错。用 Python 3.8 脚本自动生成elderly_data.sql再由 Flyway 加载# generate_elderly.py import random from datetime import datetime # 模拟真实姓名避免“张三李四” first_names [王, 李, 张, 刘, 陈, 杨, 赵, 黄, 周, 吴] second_names [伟, 芳, 娜, 敏, 静, 丽, 兰, 英, 荣, 平] third_names [军, 秀英, 敏, 静, 丽, 强, 磊, 芳, 艳, 秀兰] # 生成 50 条 sql_lines [] for i in range(1, 51): name random.choice(first_names) random.choice(second_names) random.choice(third_names) phone f1{random.choice([3, 5, 7, 8])}{random.randint(100000000, 999999999)} level random.choices([0, 1, 2, 3], weights[30, 40, 20, 10])[0] # 按比例生成失能等级 community_id random.choice([1, 2]) created_at datetime.now().strftime(%Y-%m-%d %H:%M:%S) sql_lines.append(f({i}, {name}, {phone}, {level}, {community_id}, {created_at})) # 输出 INSERT 语句 with open(elderly_data.sql, w, encodingutf-8) as f: f.write(INSERT INTO elderly (id, name, phone, level, community_id, created_at) VALUES\n) f.write(,\n.join(sql_lines)) f.write(;\n) print(✅ 50 条老人数据已生成elderly_data.sql)运行python generate_elderly.py得到elderly_data.sql再将其放入src/main/resources/db/migration/V2__insert_elderly_data.sqlFlyway 启动时自动执行。4.3 演示视频录制要点聚焦 3 个核心流程总时长控制在 3 分钟内答辩视频不是功能罗列而是讲好一个故事。建议按以下顺序录制每个环节严格计时环节操作时长关键点开场打开http://localhost:8081展示首页轮播图社区活动照片15s轮播图用真实社区照片禁用 placeholder家属端登录家属账号 → 进入“我的老人” → 点击李奶奶 → 查看“今日服务计划” → 点击“确认服药” → 弹出成功提示60s确认后立即在护理员端看到状态变更提前开两个浏览器窗口护理员端登录护理员账号 → 进入“待办列表” → 点击李奶奶记录 → 播放服药视频.m3u8 → 点击“完成服务”60s视频播放需显示进度条和清晰画面禁用黑屏占位符管理端登录管理员 → 进入“服务统计” → 查看“近7天各社区服务完成率”图表30s图表用 ECharts数据需真实来自刚才的操作结尾展示项目结构IDEA 左侧包结构、数据库表MySQL Workbench、Vue 源码vscode15s镜头扫过pom.xml、application.yml、vue.config.js关键配置提示用 OBS Studio 录制分辨率设为 1280×720帧率 30fps所有按钮点击前停顿 0.5 秒让评委看清操作背景音乐关掉只保留系统音效按钮点击声、视频播放声。5. 毕业论文与答辩技巧把技术细节转化为“问题-解法-验证”逻辑链5.1 论文第三章“系统设计”必须包含的 3 张图ER 图、微服务拆分图、时序图评审老师最关注“你是否理解系统边界”。不要用 Visio 画一堆框加箭头而是聚焦三个问题ER 图只画elderly、service_record、care_staff三张核心表用连线明确标出service_record.elderly_id → elderly.id外键关系并在service_record表旁手写注释“此处建立idx_elderly_time_status索引解决高频查询性能瓶颈”微服务拆分图虽然本项目是单体但需体现架构演进思维——用虚线框标出未来可拆分为elderly-service、service-record-service、notification-service三个模块并注明“当前阶段通过 SpringBoot Profiles 实现环境隔离dev/prod”家属确认服务时序图横向 4 列家属端 Vue、Nginx、SpringBoot、MySQL纵向箭头标注HTTP POST /api/service/confirm、UPDATE service_record SET status1、SELECT * FROM service_record WHERE id123并在 MySQL 列下方写“执行计划显示使用idx_elderly_time_status索引rows1”。5.2 答辩时被问“为什么不用 Redis 缓存”用数据说话而非理论堆砌高频问题“你们系统用了 Redis 吗” 若回答“没用”可能被质疑技术深度若硬说“用了”演示时又无法展示。正确应答模板“我们做了压测对比在 50 并发下未加 Redis 时‘查询李奶奶近3天记录’平均耗时 180ms加入 Redis 缓存后降至 45ms。但考虑到毕设演示环境为单机 MySQL且该查询已通过复合索引优化至 180ms低于用户感知阈值 200ms为降低系统复杂度、避免引入新故障点如 Redis 宕机导致雪崩我们选择暂不集成缓存。若未来扩展为多社区 SaaS 服务将基于 QPS 监控数据在service_record表读多写少的场景下用 Redis Hash 结构缓存elderly_id → [record1, record2]。”此回答包含实测数据、决策依据用户体验阈值、风险意识故障点、演进路径SaaS 场景远超“因为没学过 Redis”或“老师没要求”等无效回答。5.3 源码交付清单按答辩委员会要求整理拒绝“整个文件夹打包”高校通常要求提交源码数据库毕业论文视频演示但直接发一个 500MB 的 ZIP 会被退回。必须按标准结构组织community-care-platform/ ├── 00_README.txt # 第一行写“SpringBoot 2.7.18 Vue 3.2.45 MySQL 8.0.33” ├── 01_source_code/ │ ├── backend/ # SpringBoot 项目含 pom.xml 和 src/ │ └── frontend/ # Vue 项目含 package.json 和 src/ ├── 02_database/ │ ├── init_schema.sql # Flyway V1__init.sql 内容 │ ├── test_data.sql # V2__insert_elderly_data.sql 内容 │ └── export_data.sql # 导出当前演示数据mysqldump -u root -p community_care export_data.sql ├── 03_document/ │ ├── graduation_thesis.pdf # 论文 PDF封面含学号姓名 │ └── design_report.docx # 系统设计说明书含 ER 图、接口文档 └── 04_video/ ├── demo.mp4 # 3 分钟演示视频H.264 编码MP4 封装 └── screen_recording.mov # 备份用Apple 设备录制注意00_README.txt必须存在且首行准确这是自动化查重与环境校验的第一步export_data.sql必须包含INSERT语句而非CREATE TABLE确保评委导入后直接有数据可演示。本文还有配套的精品资源点击获取