资讯详情

基于Spring Boot的宠物成长记录平台设计与实现——全栈毕设项目思路解析

📅 2026/10/21 6:03:20 | 华诺云谱 👁 阅读
基于Spring Boot的宠物成长记录平台设计与实现——全栈毕设项目思路解析
毕设季又到了每年这个时候总有同学在选题和实现之间反复拉扯。如果你正在找一个既不算太复杂、又能把主流技术栈都串起来的题目基于Spring Boot的宠物成长记录平台是个很合适的方向。这个题目覆盖面广业务逻辑清晰从前端页面到后端接口再到数据库设计每一层都有东西可写工作量适中性价比很高。这篇文章我就围绕这个项目的设计与实现把整体思路、核心模块、数据库设计、实操过程中的难点和排查经验一并拆开讲希望能给正在做类似选题的同学一些可直接参考的内容。1. 项目整体设计与思路拆解1.1 为什么选宠物成长记录作为业务场景先说说选题本身。宠物成长记录平台这个业务场景本质上是一个面向C端的轻量级内容管理数据记录系统。核心用户是宠物主人核心诉求是记录宠物从幼年到成年的各种成长数据包括体重变化、疫苗接种、驱虫记录、日常饮食、成长相册等。这个场景非常适合作为毕业设计原因有几点第一业务边界清晰功能模块容易划分。不像电商系统那样要处理订单、库存、支付等多条复杂链路宠物成长记录的主线就是“用户-宠物-记录”三者之间的关系数据模型直观逻辑上不会绕。第二技术栈覆盖面广。Spring Boot负责后端接口MySQL存业务数据Redis可以做缓存或验证码存储前端可以用Vue也可以用Thymeleaf模板引擎文件上传可以对接本地存储或云存储这些技术组合起来就是一个标准的全栈项目答辩时技术点好讲。第三可扩展性强。如果想把项目做得有亮点可以加图表统计、健康提醒、疫苗到期推送、社区分享等功能丰俭由人。1.2 核心技术选型和理由整套系统的技术选型我建议围绕“经典够用”的原则来定后端框架Spring Boot 2.x这是目前最主流的选择自动配置机制能省掉大量XML配置开发效率高。版本上建议用2.7.x稳定且资料多遇到问题搜起来方便。持久层框架MyBatis-Plus对比原生MyBatis它内置了通用的增删改查方法对于单表操作几乎不用写SQL分页插件也是现成的能省下不少时间。数据库MySQL 8.x存储业务数据。字符集用utf8mb4因为要支持emoji表情宠物照片的备注、日记里很容易出现emoji用utf8mb4才能完整存储。缓存Redis主要用来存验证码、Token或者热点数据。如果大家的开发环境装不了Redis也可以用Spring Cache加本地缓存顶一顶但答辩时提到Redis设计的思路会更加分。前端如果基础一般用BootstrapThymeleaf服务端渲染就够了简单直接如果想展示一下前后端分离的能力可以用Vue 2/3 Element UI。这个项目后端接口设计成RESTful风格两种前端方案都能对接。文件存储宠物成长记录里面有照片上传需求头像、成长相册等。最简单的方案是上传到本地目录然后通过映射访问条件允许也可以接入对象存储。1.3 系统角色与功能边界系统涉及的参与者主要有两类管理员和普通用户。普通用户是平台的核心使用者功能包括注册登录、宠物档案管理添加/编辑/删除自己的宠物、成长记录管理为某只宠物添加体重、疫苗、驱虫、日记等记录、相册管理、健康提醒查看。管理员主要负责平台层面的监管比如用户管理、宠物类型管理狗、猫、兔子等、公告管理、数据统计概览。功能边界上要特别注意一点用户只能操作属于自己的宠物数据。这是整个系统权限校验的核心也是答辩时最容易问到的点。实现方式很简单但必须做所有涉及宠物数据的接口都要先校验当前登录用户的ID和宠物的归属用户ID是否一致。这个逻辑不是靠前端藏按钮而是后端每个接口都要严格执行。2. 数据库设计与核心细节解析2.1 数据表结构规划数据库设计是毕设的重头戏答辩时老师一定会盯着表结构和字段看。宠物成长记录平台的核心表我建议设计成以下这些不用贪多但每张表都要有存在的理由。用户表user字段包括id、username、password加密存储、nickname、avatar、phone、email、create_time、update_time、status。用户表的逻辑要干净不要放宠物相关的字段因为用户和宠物是一对多的关系宠物信息交给宠物表去维护。宠物表pet字段包括id、user_id外键逻辑关联用户表、name、breed品种、pet_type宠物类型如猫/狗、gender、birthday、weight、avatar、remark、create_time、update_time。这里pet_type既可以做成字段存字符串也可以做成字典表。建议用字典表因为管理员后台可以维护“可选的宠物类型”这样扩展性更好。成长记录表growth_record字段包括id、pet_id、record_type记录类型体重/疫苗/驱虫/饮食/日常、title、content、measure_value数值字段比如体重数值、unit、record_date、create_time。把record_type单独拎出来的好处是记录的类型是可扩展的不会因为后面加一个“洗澡记录”就要改表结构。疫苗记录表vaccine_record字段包括id、pet_id、vaccine_name、vaccine_date、next_vaccine_date、hospital、remark。如果想让项目显得更完整疫苗记录表最核心的价值是“下一次接种时间”这是做健康提醒推送的数据基础。成长相册表photo_record字段包括id、pet_id、photo_url、description、shoot_date、create_time。相册表的核心字段是photo_url存储访问路径。注意photo_url存的是相对路径或URL而不是二进制图片本身。公告表notice字段给管理员使用id、title、content、status、create_time。管理员表admin独立于用户表字段包括id、username、password、role、create_time。2.2 表关系与字段设计思路这几张表之间的关系非常明确用户1——N宠物宠物1——N成长记录宠物1——N疫苗记录宠物1——N成长相册外键在物理层面上我建议不加约束而是在逻辑层面通过查询条件控制。原因很简单物理外键在删除数据时会带来一堆麻烦比如用户要删除一只宠物如果它的成长记录、疫苗、相册都还在物理外键会拦截删除操作反而增加开发复杂度。当然这个取舍要在论文里说明白写清楚“逻辑外键代码层确保数据一致性”的设计思路这就是一个能体现出思考深度的细节。字段命名统一用下划线风格和Java实体类的驼峰命名通过MapUnderscoreToCamelCase配置做自动映射这样实体类写起来干净不用每个字段都加TableField注解。2.3 数据库设计的几个关键决策关于软删除。宠物和成长记录这类数据建议加一个deleted字段做逻辑删除默认值为0。用户删除一条记录时实际上是执行UPDATE而不是DELETE。这样做的好处是数据可恢复操作记录有迹可循。MyBatis-Plus提供了TableLogic注解加上后分页查询会自动带上deleted0的条件非常方便。关于时间字段。create_time和update_time统一用datetime类型不要用varchar存时间字符串。后续如果需要做时间范围的筛选查询datetime类型可以直接用MySQL的日期函数处理性能和数据准确性都有保障。MyBatis-Plus的字段自动填充功能可以实现在insert和update时自动写入这两个字段不用手动set值。关于权重数值的单位。体重记录存一个measure_value是不够的因为体重的单位是kg驱虫记录可能还需要写“体内驱虫/体外驱虫”这种类型描述。所以我的建议是通用的measure_value只存数字和它配套的unit字段存单位描述。在业务展示层再根据record_type拼接成“2.5kg”或“体内驱虫完成”这类可读性强的文案。3. 核心功能模块与实操要点3.1 用户注册登录与JWT鉴权用户模块是每个系统都有的但做得好不好直接关系到答辩评价。注册登录我建议采用JWTJSON Web Token做无状态鉴权。注册流程是前端提交用户名、密码、确认密码、邮箱选填后端校验用户名是否重复、密码长度是否合规、两次密码是否一致。密码存储用Spring Security自带的BCryptPasswordEncoder加密明文密码绝对不允许入库。登录流程是校验用户名和密码成功后后端返回一个JWT Token给前端。Token生成时可以放入userId、username以及过期时间然后通过拦截器或Spring Security过滤器对需要认证的接口做校验。前端拿到Token后放在HTTP Header的Authorization字段中格式是“Bearer token”。这里要重点说两个坑第一JWT的中文编码问题。如果Token里面放了username且username是中文部分版本的JJWT库在解析时会出现乱码或签名错误。解决方式是Token中只放userId和过期时间需要用户信息时再查库。第二Token过期后的前端处理。接口返回401状态码时前端需要统一拦截并跳转到登录页。这个逻辑要提前做好不然后面调试接口时会很痛苦。3.2 宠物档案管理的实现宠物档案是整个平台的数据源头所有成长记录和相册都挂在某只宠物下面。用户添加宠物时前端需要提交表单包括宠物名、品种、类型、性别、生日、初始体重、头像。后端接口要做的基础校验是宠物名不能为空、生日不能晚于今天、体重数值必须在合理范围内比如0.01kg到200kg之间。编辑和删除宠物时接口会先根据petId查出宠物信息然后校验宠物的userId是否等于当前登录用户的ID。校验逻辑放在Service层做一个公共方法比如checkPetOwner(Long petId, Long userId)各个接口直接调用避免每个业务方法里重复写这段校验代码。这里有个细节值得注意宠物头像的上传接口最好独立出来前端先调上传接口拿到头像URL再随表单一起提交。这样能避免表单提交时文件流和JSON参数混合处理的复杂性。单独的上传接口可以使用MultipartFile接收文件校验文件大小建议不超过5MB和文件类型jpg/png/webp然后存储到指定目录返回可访问的URL路径。3.3 成长记录模块的核心逻辑成长记录模块是这个项目的业务重心。它的核心价值在于以时间线的方式呈现一只宠物的成长轨迹。添加记录时用户需要选择记录关联的宠物、记录类型填写标题、内容、数值和记录日期。后端接口需要处理的是如果记录类型是“体重”则measure_value字段存储体重数值unit固定为kg。如果记录类型是“疫苗”或“驱虫”则这个记录应该同时写入成长记录表和疫苗记录表保证后续的健康提醒能拿到数据。如果记录类型是“日常”则只需要填写文字内容即可。列表查询采用分页模式按宠物ID过滤按record_date倒序排列这样前端就能呈现出时间线的效果。实现层面的一个技巧是条件构造器使用LambdaQueryWrapper代码可读性好字段名写错了在编译期就能暴露而不是运行时才报错。3.4 数据可视化与图表统计这个模块是加分项强烈建议加上。宠物成长记录的核心数据之一是体重变化把这组数据以折线图形式展示在宠物详情页能大大提升项目的演示效果。后端提供一个统计接口根据petId查询这只宠物的体重记录按record_date从旧到新排序返回一组坐标点数据。前端使用ECharts绘制折线图横轴是日期纵轴是体重数值。代码逻辑很简单但展示效果非常好答辩时可以现场演示给老师看。除了体重曲线还可以做一个疫苗到期的列表查询每个宠物最新一条疫苗记录判断next_vaccine_date和当前日期的天数差小于30天的标记为“即将到期”并在用户首页提示。这个功能实现起来不超过200行代码但对整个项目的内容丰富度提升相当明显。3.5 管理端功能与数据概览管理端的功能不需要太多有几个核心的就足够用户列表分页查看所有注册用户可以禁用/启用用户状态。宠物列表查看所有用户创建的宠物信息对违规内容可以下架。宠物类型管理维护“猫、狗、兔、仓鼠、其他”等类型标签。数据概览统计注册用户数、宠物总数、今日新增记录数用简单的统计卡片或柱状图展示在管理员首页。管理端和后端的交互方式和用户端完全一致只是接口的权限要求是管理员角色。实现方式可以是在拦截器中判断Token里的role字段也可以使用自定义注解比如RequireRole(ADMIN)在处理方法上标注即可。推荐用自定义注解的方式代码侵入性小看着也更专业。4. 实操过程与关键问题排查4.1 从零搭建项目的完整流程这里给一个可参考的实操顺序按这个顺序走下来项目框架就能比较快地搭好。第一步创建Spring Boot项目。使用Spring Initializr生成基础工程选择的依赖包括Spring Web、MySQL Driver、MyBatis-Plus手动引入、Lombok、Validation、Spring Security或只是加密工具类。注意如果不想被Spring Security的默认登录页干扰可以引入后再通过配置放行所有请求只使用它的BCrypt加密工具这在小项目中是很常见的做法但要在文档里写清楚。第二步配置application.yml。配置数据源、MyBatis-Plus的驼峰映射和分页插件、静态资源路径等。这里把端口设为8080数据库名称和用户名密码按自己的环境填。第三步创建数据库表。按前面设计好的表结构在MySQL中建表中文注释写清楚每个字段的含义。这一步一定要做扎实后续的所有开发都依赖表结构。如果动手能力稍弱可以通过Navicat图形化界面建表效率更高。第四步编写通用返回类。创建一个Result类包含code、message、data三个字段统一接口的返回格式。这样前后端交互规范前端拿到状态码就能根据code字段统一处理错误提示。所有Controller的返回值都用Result包装而不是直接返回实体类。第五步按模块开发。从用户模块开始做完一个模块测试一个模块。用Postman调接口是必须要做的步骤先测通注册登录再测宠物CRUD然后才是业务更复杂的成长记录和数据统计。第六步开发前端页面。如果前端经验不多建议先做管理端的关键页面再做用户端的首页、宠物详情页、记录添加页。页面不用多华丽但核心业务链路必须完整用户能从注册登录一路走到添加记录查看曲线。第七步联调测试并准备数据。系统跑通后要准备一两只“演示宠物”录入若干体重记录、疫苗记录和相册图片让答辩时的演示有实际数据支撑。4.2 关键代码逻辑的详细说明分页查询的通用写法。MyBatis-Plus的分页插件配置好后Service层里使用Page对象配合LambdaQueryWrapper即可。比如分页查询当前用户的宠物列表// 构造分页参数当前页、每页条数 PagePet page new Page(current, size); // 构造查询条件只查当前用户的宠物并且按创建时间倒序 LambdaQueryWrapperPet wrapper new LambdaQueryWrapper(); wrapper.eq(Pet::getUserId, userId) .orderByDesc(Pet::getCreateTime); // 执行查询分页插件会自动拼接LIMIT语句 petMapper.selectPage(page, wrapper);这个写法的好处是非常简洁而且selectPage返回的Page对象里已经包含了总记录数、总页数、当前页数据列表前端分页组件需要的字段基本都有。JWT工具类的简要结构。核心方法有三个生成Token、解析Token、判断Token是否过期。public String generateToken(Long userId) { // 设置主题为userId过期时间2小时签名密钥从配置读取 return Jwts.builder() .setSubject(String.valueOf(userId)) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() 86400000)) .signWith(key, SignatureAlgorithm.HS256) .compact(); } public Long getUserIdFromToken(String token) { // 解析Token如果签名非法或过期这里会抛出异常 Claims claims Jwts.parserBuilder() .setSigningKey(key) .build() .parseClaimsJws(token) .getBody(); return Long.valueOf(claims.getSubject()); }使用时的注意点是在拦截器中获取到userId后要把它放入Request的Attribute中比如request.setAttribute(userId, userId)后续的Controller方法就可以直接从Request中取避免解析两次Token。文件上传实现的关键点。本地存储方案虽然简单但有两个细节要处理好一是文件命名要用UUID避免上传相同名字的图片时互相覆盖二是上传目录需要和静态资源映射绑定比如把“/images/**”映射到本地磁盘的“/uploads/”目录这样前端可以直接拼接URL访问图片。// 处理文件上传 String originalFilename file.getOriginalFilename(); String suffix originalFilename.substring(originalFilename.lastIndexOf(.)); String fileName UUID.randomUUID().toString().replace(-, ) suffix; // 确保目录存在 File dir new File(uploadPath); if (!dir.exists()) { dir.mkdirs(); } // 保存文件 file.transferTo(new File(uploadPath fileName)); // 返回访问路径 return /images/ fileName;4.3 实操过程中的典型问题与排查思路把真实的踩坑经历整理成速查表比泛泛而谈要有用得多。下面是这个项目里比较常见的几类问题。问题一登录接口报403或401页面进不去排查顺序很明确先看请求有没有到达Controller在方法入口打个日志再看拦截器有没有拦截该路径检查拦截器注册的excludePathPatterns是否漏了登录和注册接口然后看Token解析有没有报错签名的key是否和生成时一致。大部分这类问题都出在拦截器放行配置上因为Spring Security或拦截器的URL匹配规则很容易写错比如用/*只匹配一层路径而实际请求是两层。问题二前端提交JSON数据后端接收不到返回参数缺失百分之九十的原因是前端没有设置请求头Content-Type为application/json或者后端接收参数用的对象没有加RequestBody注解。另一个容易忽略的坑是前端传的字段名和后端实体类的属性名不一致比如前端传create_time而后端是createTimeJSON序列化默认情况下不会自动转化。问题三分页查询出来的数据重复或缺失这个和LIMIT语句的排序不稳定有关。当你用create_time作为排序字段时如果同一秒插入了多条数据数据库返回的顺序可能不稳定。解决方式在排序字段后面追加一个唯一字段比如orderByDesc(createTime).orderByDesc(id)保证排序结果稳定。问题四上传图片之后显示不出来如果静态资源映射没配好数据库的照片URL地址写的是/images/xxx.jpg但浏览器访问这个路径返回404。此时要检查项目里有没有一个WebMvcConfigurer配置类把虚拟路径映射到实际存储目录。另外一个常见原因上传文件的绝对路径中包含中文字符导致Tomcat解析请求时对某些字符处理异常。统一用英文目录可以规避这个问题。问题五修改后页面不生效数据感觉“没变”大概率是浏览器缓存特别是CSS和JS文件。开发阶段可以在浏览器控制台禁用缓存或给静态资源请求地址加版本参数。另外如果用了后端模板渲染和前端SPA混合开发路由配置混乱也会导致页面加载了旧的打包文件。4.4 让项目更完整的几个加分细节在做完主体功能之后时间允许的话可以补充下面这几个细节它们不会增加太多工作量但对项目的完整度和答辩效果有明显帮助。统一异常处理。定义一个GlobalExceptionHandler通过RestControllerAdvice捕获业务异常和参数校验异常统一返回Result格式。这样代码里就不用到处写try-catch了Controller层能保持非常干净数据库异常、空指针异常等也不会直接以堆栈的形式暴露给前端。参数校验合理化。后端接收参数的实体类上加上NotBlank、NotNull等校验注解Controller方法参数前加Validated。这样表单提交时后端能自动完成非空校验和格式校验省掉手写大量if判断的时间。部分接口的防重复提交。比如用户短时间内重复点击“添加记录”按钮会产生多条重复记录。简单的处理方式利用Redis的setnx命令以userId和接口名拼接的key设置几秒钟的过期时间重复请求直接拦截。这个机制在答辩时讲出来会显得你有并发思维。操作日志。记录关键操作登录、新增宠物、修改记录、删除记录到一张日志表管理端可以查看最近操作记录。这样项目的完整性会好很多也让管理员模块不是只有增删改查而是有监控意味的功能。图形验证码。登录页加一个简单的验证码后端用Java生成图片或直接使用现成工具类把验证码文本存到Redis并设置有效期。这个功能实现成本不高但能让项目看起来更真实尤其是演示时输入验证码会让人感知到工程的完整度。5. 文档结构、答辩准备与经验总结5.1 毕业论文的章节脉络与写作思路毕设文档和项目代码一样重要甚至在很多评审眼中文档占的比重更大。这个题目的论文结构比较常规但每章怎么写是有讲究的。绪论部分要讲清楚研究背景、国内外现状和研究意义。注意这里的“国内外现状”千万不要抄一些泛泛而谈的套话而应该结合宠物经济的增长趋势、服务业数字化的大背景把选题逻辑写顺。需求分析章节要写两个维度功能需求和非功能需求。功能需求画出用例图每个角色对应哪些用例要写清楚非功能需求要提性能要求如接口响应时间不超过2秒、安全性要求密码加密、权限校验、可用性要求界面友好、操作简单。系统设计章节要体现三层逻辑总体架构设计前端、后端、数据库三层分离、功能模块设计每个模块的流程图或时序图、数据库设计E-R图和每张表的字段说明。数据库设计是这一章的亮点字段注释要详尽外键逻辑要说清楚。系统实现章节按模块写每个模块配核心代码段和界面截图。这里要控制代码量展示的是关键实现而不是把整个类贴上去。每个模块写清楚核心逻辑和遇到的难点能大幅提升文档的可读性。系统测试章节要分功能测试和性能测试功能测试设计核心测试用例表输入、步骤、预期结果、实际结果性能测试可以简单用Postman或者JMeter做一个并发请求的响应测试记录下响应时间和吞吐量。5.2 答辩演示前要准备的材料答辩演示不是开发过程的重演而是把项目的精华有逻辑地展示出来。建议准备一份10分钟左右的演示路径先是首页和注册登录5秒内展示出系统能正常访问然后是宠物档案创建演示时可以现场新建一只虚拟宠物接着添加体重记录进入详情页面展示体重曲线图这里最好有一组已经录入好的数据然后是疫苗记录和到期提醒的展示最后是管理端页面展示用户管理和数据概览。演示过程中有两点要注意一是提前检查网络环境如果答辩现场没有外网本地启动的MySQL和Redis要在自己的电脑上确保运行正常二是准备数据要充足用真实宠物名、真实日期录入不要现场临时编造数据。回答问题时高频问题主要集中在MyBatis-Plus相比MyBatis的优势、JWT相比Session的优势、为什么用逻辑外键、分页怎么实现的、权限校验怎么做、项目有哪些可以改进的地方。这些问题在文档里其实都有涉及答辩前过一遍即可。5.3 项目后续的扩展方向一个项目的价值很大程度上体现在可扩展性上这也是答辩时展示思考深度的地方。如果继续迭代有几个方向值得聊一聊接入宠物医院接口实现线上预约加入宠物丢失求助社区引入消息推送在疫苗到期前通过邮件或微信模板消息提醒用户对接第三方登录将体重数据接入智能设备通过蓝牙获取电子秤数据。这些方向不需要全部实现但论文的结尾部分如果能有一小节写“未来展望”且每个方向都能结合技术路线讲几句比如消息推送用消息队列智能设备接入用蓝牙协议解析会让评审觉得你不只是完成了代码而是对系统的演进有真实思考。写在最后的一点建议根据我带过的和见过的同类项目经验宠物成长记录平台这个选题最终拿到的评价往往取决于三个维度的完成度核心业务链路是否走通、权限控制是否严密、数据可视化是否有亮点。代码量反而不是第一位的一个逻辑清晰、注释规范、接口设计合理的中小型项目远比一个功能堆砌但结构混乱的项目更容易获得认可。做这个项目的过程中我自己的体会是一开始不要急着写代码把表结构设计好、把接口文档列清楚后续开发会顺畅很多。很多同学在开发中反复改代码回头一看基本都是因为表结构设计时漏了字段或者接口参数定义不明确导致的返工。这类项目的体量不大但对工程化的基本素养要求还是挺完整的——从建表、编码、测试到文档撰写一条龙走下来应对毕业设计是足够扎实的。最后再分享一个实用的小技巧项目开发过程中记得频繁git提交每个功能模块完成一个就提交一次写清楚commit信息。这不仅是为了防止代码丢失更重要的是答辩前你需要快速回顾每个模块的开发脉络清晰的提交记录能帮你更高效地组织答辩内容。祝大家毕设顺利答辩从容。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑