☰
Spring Boot智慧养老平台开发实战:从数据库设计到答辩全流程
2026/10/6 17:29:17 网站建设 项目流程

简介:基于Spring Boot Web的智慧养老平台毕业设计资源包,包含毕业论文、答辩PPT、全套源代码与演示视频,可直接用于项目参考和二次开发。项目环境涵盖JDK1.8、Tomcat7、MySQL5.7等,设计内容包括用户管理流程、个人中心、登录流程、软件功能模块、数据库概念与物理模型、系统测试等完整开发环节。资源共954个文件,以195个Java源码、164个JavaScript、162个SVG、69个HTML、65个Vue组件、53个CSS样式及SQL脚本为主,另含mp4演示视频和docx论文,压缩包约50.79MB。其中Java与Vue文件对应后端与前端实现,SQL脚本用于数据库初始化,演示视频可直观了解系统操作流程,目录结构清晰便于按模块学习。已有301人学习下载,适合希望快速搭建Spring Boot与Vue项目、参考毕业论文框架或扩展养老平台功能的毕业设计开发者;通过完整源代码、设计文档和操作录屏,能系统掌握从数据库建表到后台管理、老人端功能实现的开发脉络。

1. Spring Boot Web智慧养老平台:毕设选它,论文和代码能一起交差

又到了毕业设计选题季,很多同学卡在同一个问题上:题目太大做不完,太小没东西写。基于Spring Boot Web的智慧养老平台属于典型的“中等规模、业务闭环”选题——后端用Spring Boot撑起REST接口,前端做管理端和移动端页面,数据落到MySQL里,覆盖老人档案、健康记录、活动报名、工单报修这些真实业务。它既能体现Java基础、Spring Boot框架、Web开发三条主线,又不会像“电商系统”那样要跟支付、库存死磕。适合想一个人从零写完整套代码、同时还要交毕业论文和PPT的本科生,也适合拿来当Spring Boot整合MyBatis-Plus的练手项目。下面我把从建库到答辩的完整路径拆给你。

2. 智慧养老平台的功能架构与Spring Boot技术选型:先把模块拆明白再动手

很多毕设翻车不是因为代码写不出来,而是开头没把模块拆清楚,做到一半才发现页面和接口对不上。智慧养老平台的业务边界其实很清晰:养老机构要管老人、管护工、管工单、管活动。先把这四个词落地成模块,代码结构就稳定了。

2.1 三个终端的模块划分:管理端、护工端、老人端分别管什么

常见的做法是分三个角色终端,权限从高到低排列。管理端给机构行政人员用,负责基础数据维护:老人入住登记、护工排班、活动发布、工单分配、健康档案查看。护工端主要处理两类事:接收系统派发的照护任务、上报老人健康数据。老人端则更轻量,家人代操作也常见,核心是不在手机端搞复杂表格。我的建议是老人端只保留健康档案查询、活动报名、家属留言三块,把CRUD压力全部留在管理端。

三个终端共用同一个Spring Boot服务,不拆成三个独立应用。原因很实际:拆三个服务意味着要处理注册中心、服务间调用、统一认证,这些超出毕设的合理范围,还会把论文篇幅浪费在架构图上而不是业务上。你只需要在Controller层按/api/admin/**、/api/staff/**、/api/elder/**做URL前缀区分,配合拦截器控制角色即可。这样即使用同一个登录接口,也能通过数据库里的角色字段决定前端渲染哪些菜单。

模块划分表可以当论文里的功能结构图来用,我一般会让读者直接照这个结构画用例图:

终端核心功能数据落点
管理端老人档案、床位/房间管理、护工排班、工单派发、活动发布、数据统计老人表、工单表、活动表
护工端查看今日任务、上报老人体征、提交异常工单健康档案表、工单表
老人端健康档案查询、活动报名、家属留言健康档案表、活动报名表

2.2 Spring Boot + MyBatis-Plus + MySQL的选型理由与版本边界

技术栈选型要回答两个问题:为什么用Spring Boot,以及哪个版本。Spring Boot的价值在于它把Web开发里“配Tomcat、配Spring MVC、配JSON转换”这些重复劳动全干了,你在pom.xml里引一个spring-boot-starter-web,一个main方法就能把服务跑起来。这对毕业设计来说是决定性的——你不需要在环境搭建上花两周时间。

ORM层用MyBatis-Plus而不用原生MyBatis,理由更直接:单表CRUD不用写SQL,save、getById、lambdaQuery直接出结果。智慧养老平台这种系统的查询基本都走单表或多表联查,MyBatis-Plus的LambdaQueryWrapper能覆盖九成场景,剩下的复杂统计你再用@Select注解手写XML也不迟。我见过太多同学用JPA写一半发现复杂查询失控,换成MyBatis-Plus后代码量肉眼可见地降下来。

版本边界千万注意:Spring Boot 3.x要求JDK 17起步,而很多学校实验室电脑装的是JDK 8。如果你不确定服务器环境,直接锁定Spring Boot 2.7.x + JDK 8 + MyBatis-Plus 3.5.x,这个组合最稳。Spring Boot 2.7仍在官方维护期内,而且网上能搜到的教程、踩坑贴绝大多数都基于这个版本,遇到报错好查。

2.3 标准分层项目结构与pom依赖:照着建不迷路

Spring Boot项目结构不是随便分的,它直接决定你论文第三章的写作顺序。我习惯按controller、service、mapper、entity、config、common六层组织,其中common放统一返回结果Result和全局异常处理。一个标准的包结构长这样:

src/main/java/com/smart/aging ├── controller # 接口层,只做参数接收和结果返回 ├── service # 业务层,事务、校验、业务规则 │ └── impl # 业务实现类 ├── mapper # MyBatis-Plus的Mapper接口 ├── entity # 数据库实体类 ├── config # WebMvc配置、Interceptor注册 └── common # Result、异常枚举、常量

pom.xml里最核心的依赖只有四个:web、mybatis-plus-boot-starter、mysql驱动、lombok。lombok用来自动生成getter和setter,能让实体类短一半。这里的mybatis-plus-boot-starter版本我推荐3.5.3.1,这个版本对Spring Boot 2.7兼容良好,分页插件用法也稳定:

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>

逻辑说明:这里的mysql-connector-j是MySQL 8的驱动坐标,如果你用MySQL 5.7就得换成mysql-connector-java并指定版本。lombok标记optional是为了防止它被传递到下游依赖里,这只是工程规范,不影响运行。加了这四个依赖后启动Spring Boot,看到Tomcat started on port 8080,项目骨架就算立住了。

3. 智慧养老平台的数据库设计:老人档案、健康数据与工单怎么建表

数据库是论文里最好凑字数也最容易被导师挑刺的部分。图好看没用,字段设计要能自圆其说。智慧养老平台的数据核心是“老人”和“健康数据”,所有模块都围绕这两张主表展开。

3.1 核心表结构梳理:八张表覆盖主要业务流程

整个平台建议控制在八到十张表,太多表会让论文的E-R图画到崩溃,太少则显得系统单薄。我的推荐列表是:老人信息表、护工信息表、用户登录表、健康档案表、工单表、活动表、活动报名表、公告表。其中的逻辑是:老人与健康档案是一对多,老人与活动报名是一对多,工单表里同时冗余老人ID和护工ID,避免建第三张关联表。

这八张表各司其职,不要试图扩展出排班表、床位数明细表、费用表。毕设的系统边界是“能演示完整业务流程”,不是“能支撑真实养老院运营”——这一点想清楚,表设计就能收得住。真实项目需要十几个表才能跑通的细节,在毕设里会变成重复造轮子。

3.2 建表SQL示例:老人信息表与健康档案表的字段设计

老人信息表是系统的地基,字段要覆盖“这个老人是谁、住哪、什么照护等级、紧急情况下联系谁”。下面是建表SQL,字段注释写在每条字段后面,这在论文里可以直接截图使用:

CREATE TABLE `elder_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL COMMENT '老人姓名', `gender` tinyint(1) DEFAULT NULL COMMENT '性别 0女 1男', `age` int(11) DEFAULT NULL COMMENT '年龄,冗余字段,可用身份证解析', `id_card` varchar(18) DEFAULT NULL COMMENT '身份证号,需做唯一约束', `phone` varchar(20) DEFAULT NULL COMMENT '老人本人电话,可空', `room_no` varchar(20) DEFAULT NULL COMMENT '房间号,如 A-301', `care_level` tinyint(1) DEFAULT '1' COMMENT '护理等级 1自理 2半自理 3全护理', `emergency_contact` varchar(50) DEFAULT NULL COMMENT '紧急联系人姓名', `emergency_phone` varchar(20) DEFAULT NULL COMMENT '紧急联系人电话', `status` tinyint(1) DEFAULT '1' COMMENT '状态 1在住 0退住', `deleted` tinyint(1) DEFAULT '0' COMMENT '逻辑删除标记', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_id_card` (`id_card`), KEY `idx_room_no` (`room_no`), KEY `idx_care_level` (`care_level`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='老人信息表';

逻辑说明:id_card加唯一索引是为了防止同一个人重复入住,这在答辩时是一个很好的“业务思考”讲点。deleted字段配合MyBatis-Plus的逻辑删除功能,后面写代码时不需要手动加where deleted = 0。care_level用tinyint而不是varchar,是为了在Java端用枚举做映射,避免“自理/半自理”这样的中文文本散落在代码各处。

健康档案表记录老人每次的体检或日常体征数据,是系统里数据量增长最快的表。它的设计原则是“一条记录一个测量时间点”,不要试图用一行存最新数据:

CREATE TABLE `health_record` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `elder_id` bigint(20) NOT NULL COMMENT '老人ID,关联elder_info.id', `record_type` varchar(20) NOT NULL COMMENT '类型:体检/日常/异常上报', `blood_pressure` varchar(20) DEFAULT NULL COMMENT '血压,格式"130/85"', `heart_rate` int(11) DEFAULT NULL COMMENT '心率 次/分', `blood_sugar` decimal(5,2) DEFAULT NULL COMMENT '血糖 mmol/L', `temperature` decimal(4,2) DEFAULT NULL COMMENT '体温 ℃', `remark` varchar(500) DEFAULT NULL COMMENT '备注,异常情况描述', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '测量时间', PRIMARY KEY (`id`), KEY `idx_elder_time` (`elder_id`, `create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='健康档案表';

3.3 表关系与三个设计坑:逻辑删除、时间字段、编码规则

表之间常见的问题是外键到底建不建。我的建议是:逻辑上关联,物理上不建外键约束。理由很现实——外键约束在删除老人或护工时经常触发拒绝,演示环节一旦报错就会卡住;而且MyBatis-Plus的关联查询靠代码控制,不需要数据库外键。你在论文里画清楚E-R图即可。

第一个坑是逻辑删除字段的命名。MyBatis-Plus中logic-delete-field默认找deleted字段,如果取名is_deleted就得在yml里显式声明。最稳妥的做法是统一用deleted,类型设为tinyint(1),不要用datetime做删除标记,否则查询条件会变复杂。

第二个坑是时间字段类型。Java端如果使用LocalDateTime,数据库端就用datetime;如果使用Date,数据库用timestamp。混用会在JSON序列化时出现格式错乱。建议老夫老妻式组合:Java用LocalDateTime,数据库用datetime,并配置spring.jackson.date-format统一格式。

第三个坑是id_card的唯一索引要处理历史脏数据。如果你导入了测试数据,可能已经有重复身份证号,建索引会直接失败。常见做法是写一条清理SQL,把重复数据标记或合并后再加索引。这个问题不大,但是等你在演示时才发现就晚了。

4. Spring Boot后端核心实现:配置文件、登录拦截与业务接口怎么写

数据库设计完,接下来就是把后台跑起来。这一章是最能体现Spring Boot开发效率的地方,也是你在简历上敢写“熟练使用Spring Boot”的底气来源。

4.1 application.yml配置:端口、数据源、Jackson与MyBatis-Plus

Spring Boot的配置全集中在application.yml,毕业设计基本不需要拆成多环境配置,但要把几个关键项写对。server.port默认是8080,如果你本机被占用,改成8081即可。下面的配置是我常用的模板,覆盖了数据源、JSON格式、MyBatis-Plus的逻辑删除和日志:

server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/smart_aging?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 id-type: assign_id

逻辑说明:map-underscore-to-camel-case让数据库的room_no自动映射到Java字段roomNo,这是MyBatis-Plus默认开启的,写上是为了让你心里有数。logic-delete-field: deleted声明逻辑删除字段,之后所有deleteById操作都会变成update ... set deleted=1,而不是物理删除,相当于给数据留了后悔药。id-type: assign_id用雪花算法生成主键,比数据库自增更灵活,适合将来分表,虽然毕设用不到,但论文里写一句“使用雪花算法避免主键冲突”会加分。

4.2 登录鉴权:用拦截器统一处理未登录请求

登录鉴权方案在Spring Boot里有两派:JWT和Session拦截器。商业项目用JWT多,但毕业设计我更推荐Session+拦截器——实现简单、答辩容易讲清楚、不需要处理Token过期刷新这种隐蔽问题。核心代码是一个HandlerInterceptor的实现类加上一个WebMvcConfigurer注册类:

@Component public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object userId = request.getSession().getAttribute("userId"); if (userId == null) { response.setStatus(401); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write("{\"code\":401,\"msg\":\"未登录或登录已过期\"}"); return false; } return true; } }

注册拦截器时需要排除登录接口本身,否则会死循环。这里还可以做角色权限校验,getAttribute("role")拿到角色后,判断当前请求前缀是否匹配,不匹配就返回403:

@Configuration public class WebConfig implements WebMvcConfigurer { @Resource private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns("/api/**") .excludePathPatterns("/api/login", "/api/register", "/api/common/**"); } }

逻辑说明:拦截器只对/api/**生效,静态资源不在拦截范围内。这里要特别注意的是,如果你把前端Vue打包后放在Spring Boot的static目录下,前端页面属于静态资源,不需要拦截;但前端调用的接口会走拦截器。答辩时你可能会被问到“用户的Session什么时候失效”,答案是Tomcat默认30分钟,也可以在yml里通过server.servlet.session.timeout调整。这个回答能体现你对Web基础的理解。

4.3 健康档案新增与分页查询:Service层事务与参数校验

健康档案是系统的核心业务,写一个Controller和Service示例,你能照葫芦画瓢写其他所有模块。Controller只做三件事:接收参数、调用Service、返回Result。本身不写业务逻辑,这是分层架构的核心原则:

@RestController @RequestMapping("/api/health") public class HealthRecordController { @Resource private HealthRecordService healthRecordService; @PostMapping("/add") public Result add(@RequestBody @Valid HealthRecord record) { healthRecordService.addRecord(record); return Result.ok("记录成功"); } @GetMapping("/elder/{elderId}") public Result pageList(@PathVariable Long elderId, @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size) { Page<HealthRecord> result = healthRecordService.pageByElder(elderId, page, size); return Result.ok(result); } }

对应的Service实现类里,addRecord方法加了@Transactional注解,因为一次建档可能同时写入健康档案表和操作日志表,任何一步失败都要回滚。分页查询用的是MyBatis-Plus的Page对象,lambdaQuery写法是3.x版本推荐的,类型安全,不会出现手写SQL时拼错字段名的问题:

@Service public class HealthRecordServiceImpl extends ServiceImpl<HealthRecordMapper, HealthRecord> implements HealthRecordService { @Override @Transactional(rollbackFor = Exception.class) public void addRecord(HealthRecord record) { record.setCreateTime(LocalDateTime.now()); this.save(record); } @Override public Page<HealthRecord> pageByElder(Long elderId, Integer page, Integer size) { return this.lambdaQuery() .eq(HealthRecord::getElderId, elderId) .orderByDesc(HealthRecord::getCreateTime) .page(new Page<>(page, size)); } }

逻辑说明:@Transactional(rollbackFor = Exception.class)的意思很明确——只有RuntimeException时Spring默认回滚,必须显式声明Exception.class才能让所有异常都触发回滚。这是Java面试题里常考的Spring事务细节。分页参数page和size都加了默认值,即使前端没传也不会报错,这个细节在答辩演示时能帮你避免不少尴尬场面。

5. 智慧养老平台常见问题排查:启动失败、数据异常与404的5个坑

我从带毕设的经验里挑了五个出现频率最高的坑,每个都按现象、原因、解决的顺序写清楚。这些坑不踩一遍,演示视频很难一遍录完。

5.1 Spring Boot版本与JDK不匹配:启动即报UnsupportedClassVersionError

现象:启动类刚运行,控制台直接抛UnsupportedClassVersionError,提示class file has wrong version 61.0, should be 52.0。原因是Spring Boot 3.x编译要求JDK 17,而你用的是JDK 8。解决方式有两种:本机换成JDK 17,或者把项目降级到Spring Boot 2.7.x。考虑到绝大多数学校的运行环境,我建议直接降级到2.7.x并锁定<java.version>1.8</java.version>。排查时先用java -version确认当前JDK版本,再检查pom.xml里的spring-boot-starter-parent版本号,两者对齐就能解决。

5.2 MySQL 8连接被拒:Public Key Retrieval与时区问题

现象:项目启动时数据源初始化失败,报Public Key Retrieval is not allowed,或者The server time zone value '�й���ʱ��' is unrecognized。原因是MySQL 8默认的认证插件是caching_sha2_password,JDBC驱动在连接时需要显式允许公钥检索;而时区报错则是因为MySQL和JDBC之间没有约定时区。解决方案是在JDBC URL上追加两个参数:allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai。如果你用的是MySQL 5.7,则不存在这两个问题,只需要useSSL=false即可。这个坑在高版本MySQL上几乎必踩,记住参数就好。

5.3 前端Vue打包后放不进Spring Boot:页面404与接口跨域

现象:Vue项目npm run build后把dist目录拷到src/main/resources/static下,启动Spring Boot访问首页白屏或404,接口却正常。原因是Vue Router默认使用history模式,刷新或直接访问子路由时,Spring Boot找不到对应的静态文件路径。解决方法是把Vue Router改成hash模式,或者在Spring Boot里写一个转发控制器,将非接口请求转发到index.html。毕业设计最省事的方案是改用hash模式,因为不需要额外代码,路由地址从/health/list变成/#/health/list,代价是URL不够美观,但完全不影响演示和评分。

5.4 LocalDateTime序列化格式混乱:前端拿到一串带T的字符串

现象:接口返回的时间字段长这样2024-05-20T10:30:00,前端想显示2024-05-20 10:30:00,格式对不上。原因很简单:Jackson默认序列化LocalDateTime时使用ISO-8601格式,天然带T。解决方案是在application.yml里配置spring.jackson.date-format和spring.jackson.time-zone。这里有个容易漏的点:date-format对java.util.Date生效,而对LocalDateTime则需要在Java字段上加@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")注解。我在前面给的yml配置里写了统一格式,但如果你实体类里混用了两种时间类型,注解才是治本方案。

5.5 逻辑删除生效后关联查询查不到数据

现象:某条档案被“删除”后,前端列表页正常不显示,但管理端的统计报表算总数时把它漏掉了,数字对不上。原因是MyBatis-Plus的deleted字段只在单表查询时自动拼接条件,如果你手写了多表联查SQL,没有在WHERE里加elder_info.deleted = 0,就会把已删除数据也算进去。解决方法是统一规范:所有手写SQL都加上deleted判断,或者用MyBatis-Plus的逻辑删除自动注入功能。排查这类问题,先看控制台打印的SQL日志,log-impl已经配置了StdOutImpl,每一条查询语句都会原样打印,一眼就能发现少了条件。

6. 毕业答辩与演示视频的准备技巧:把系统讲成论文的素材库

代码写完之后,毕业设计还有一关:毕业论文和PPT。很多同学代码做得不错,论文却写得像用户手册,结果答辩被导师追问“你的创新点在哪”。我的做法是:把系统的核心接口和流程图直接转成论文素材,每个Controller对应论文第三章的一节,每个业务点对应一个截图。

PPT不要超过12页,结构是:选题背景一页、功能架构一页、技术架构一页、数据库E-R图一页、核心功能演示五页、总结与展望一页。演示视频控制在5到8分钟,按“登录→老人建档→健康数据录入→活动发布→工单流转”这条主线来录,中间不要切屏到IDE写代码,也不要在录完才发现某个页面没填充数据。先准备一份带假数据的演示账号,数据越真实,答辩效果越好。

答辩时的高频问题集中在两处。第一处是“为什么选Spring Boot”,回答要点是自动配置和生态成熟,而不是“因为它火”。第二处是“你这个系统的难点在哪”,这时把第4章的@Transactional事务回滚、第3章的逻辑删除设计、第5章的时区问题处理讲出来,导师基本不会再追问。如果被问到“后续怎么扩展”,说“接入消息推送做异常告警”和“加ECharts做健康趋势分析”都是安全的方向。

我做这个项目时最后悔的一件事是把大量时间花在控制台打印调试上,而没有一开始就打开控制台的SQL日志。你要是按照这篇笔记走,从建表到录完演示视频,两个星期足够。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询