
简介这是一套面向高校计算机相关专业学生与Java初学者整理的宠物管理系统毕业设计完整资料围绕宠物网站的设计与实现展开适合需要完成课程设计、毕业设计或希望以真实项目练手Java Web开发的学习者。压缩包共14个文件约132.62MB包含4个mp4项目辅导视频、3个doc论文与任务书文档、1个pptx答辩演示、1个sql数据库脚本、1个zip源码包以及png界面截图和说明txt覆盖从部署到功能演示的完整链路。系统分为前台与后台两大模块前台支持用户登录注册、商品查找与类别导航后台由管理员完成订单、商品、公告、会员、用户及个人信息维护等操作并对核心数据表结构做了详细说明。视频按数据库创建与项目运行、前台模块、后台商品用户模块、系统模块分节讲解便于对照源码理解实现思路。目前已有267人学习可作为毕业设计选题与Java Web实战的参考方案。1. 宠物管理系统到底在管什么从一张寄养单说起宠物医院前台最怕的不是忙是乱。一只金毛寄养三天主人临时加一次驱虫中间换了粮出院时还要补打一针疫苗——这些信息如果散落在纸质登记本、微信聊天记录和前台脑子里月底对账一定翻车。基于 JAVA 的宠物管理系统要解决的就是把「宠物档案、主人信息、寄养/诊疗记录、疫苗驱虫提醒、费用结算」这几件事收进一个数据库让每一次操作都有迹可循。它适合两类人一是计算机专业做课程设计或毕业设计的学生需要一套能跑通、能讲清楚、能写进论文的完整项目二是刚接手小型宠物店或诊所信息化的小团队想用一套可控的源码改出自己的业务逻辑。JAVA 在这里的价值不是「因为学校教这个」而是生态成熟、数据库连接稳定、后期加权限和报表都方便。下面按「先跑起来、再改得动、最后讲得清」的顺序拆开讲。2. 技术选型与数据库设计为什么是 Spring Boot MyBatis MySQL2.1 三层架构不是摆设它决定了你改需求时改哪一层常见做法是 Controller 接请求、Service 写业务规则、Mapper 管数据库读写。宠物管理系统的业务规则其实不少寄养按天计费、疫苗到期提前提醒、同一主人名下多只宠物要能一起查。如果把这些逻辑全塞进 Controller后面加一个「会员折扣」就要翻遍所有接口。分层之后改计费规则只动 Service改字段只动 Mapper 和实体类。实体类建议至少这几张表owner主人、pet宠物、boarding寄养记录、medical_record诊疗记录、vaccine疫苗记录、bill账单。表之间用外键或逻辑外键关联宠物表里放owner_id寄养表里放pet_id。这里有个血泪经验不要用宠物名做关联字段重名太常见一定要用自增主键或业务编号。2.2 建库建表的最小 SQL 与字段说明下面这段 SQL 可以直接在 MySQL 里执行建一个能支撑基本业务的库。字符集用utf8mb4否则宠物昵称里的特殊符号会存成问号。CREATE DATABASE pet_manage DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE pet_manage; CREATE TABLE owner ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL COMMENT 主人姓名, phone VARCHAR(20) NOT NULL COMMENT 联系电话, address VARCHAR(200) COMMENT 地址, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) COMMENT 宠物主人表; CREATE TABLE pet ( id BIGINT PRIMARY KEY AUTO_INCREMENT, owner_id BIGINT NOT NULL COMMENT 关联主人, pet_name VARCHAR(50) NOT NULL COMMENT 宠物名, species VARCHAR(20) COMMENT 种类猫/狗/其他, breed VARCHAR(50) COMMENT 品种, birth_date DATE COMMENT 出生日期, weight DECIMAL(5,2) COMMENT 体重kg, INDEX idx_owner (owner_id) ) COMMENT 宠物表; CREATE TABLE boarding ( id BIGINT PRIMARY KEY AUTO_INCREMENT, pet_id BIGINT NOT NULL, check_in DATE NOT NULL COMMENT 入住日期, check_out DATE COMMENT 离店日期, daily_price DECIMAL(8,2) NOT NULL COMMENT 每日单价, status TINYINT DEFAULT 1 COMMENT 1在住 2已离店, INDEX idx_pet (pet_id) ) COMMENT 寄养记录表;字段说明owner_id和pet_id用 BIGINT 是为了避免后期数据量大时改类型daily_price存在寄养记录里而不是宠物表里因为不同时期价格可能调整历史账单不能被新价格污染status用数字而不是字符串查询和索引效率更高。建完表先手动插两条测试数据确认外键逻辑没问题再写代码。2.3 用 MyBatis 写第一个可运行的查询接口Spring Boot 项目里application.yml配好数据库连接然后写 Mapper 接口和 XML。下面是一个按主人手机号查其名下所有宠物的例子。// PetMapper.java Mapper public interface PetMapper { // 根据主人手机号查询宠物列表 ListPet selectByOwnerPhone(Param(phone) String phone); }!-- PetMapper.xml -- select idselectByOwnerPhone resultTypecom.example.pet.entity.Pet SELECT p.* FROM pet p LEFT JOIN owner o ON p.owner_id o.id WHERE o.phone #{phone} /select逻辑说明用 LEFT JOIN 而不是 INNER JOIN是为了防止主人信息缺失时宠物直接查不出来方便排查脏数据。#{phone}是预编译占位符能防 SQL 注入不要写成${phone}。参数说明Param(phone)里的名字要和 XML 里#{}保持一致否则启动就报绑定异常。写完先写一个 JUnit 测试或直接用 Postman 调 Controller确认返回 JSON 里宠物列表不为空再继续做新增和修改。3. 核心功能落地寄养计费、疫苗提醒与增删改查3.1 寄养费用计算别把日期差算成天数差寄养费用最常见的错误是用check_out - check_in得到毫秒数再除以 86400000结果住 3 天算成 2 天。正确做法是按自然日计算入住当天算一天离店当天不算。下面是一个 Service 层的方法。public BigDecimal calcBoardingFee(LocalDate checkIn, LocalDate checkOut, BigDecimal dailyPrice) { if (checkOut null) { checkOut LocalDate.now(); // 未离店按当前日期试算 } long days ChronoUnit.DAYS.between(checkIn, checkOut); if (days 0) { days 1; // 当天入住当天走至少收一天 } return dailyPrice.multiply(BigDecimal.valueOf(days)); }逻辑说明用ChronoUnit.DAYS直接算日期差避免时区和毫秒误差。参数说明dailyPrice用 BigDecimal不要用 double否则 0.10.2 这类精度问题会让账单出现 0.30000000000000004。如果业务规定「住满 24 小时才算一天」那就要用 LocalDateTime 并额外判断小时数但大多数宠物店按自然日结算上面这个版本够用。3.2 疫苗到期提醒用 SQL 筛比在 Java 里循环靠谱疫苗提醒的逻辑是查出所有next_date在当前日期之后 7 天内的记录。不要在 Java 里把所有疫苗记录查出来再循环判断数据量一大就慢。直接在 Mapper 里写条件查询。select idselectExpiringVaccines resultTypecom.example.pet.entity.Vaccine SELECT v.*, p.pet_name, o.phone FROM vaccine v JOIN pet p ON v.pet_id p.id JOIN owner o ON p.owner_id o.id WHERE v.next_date BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 7 DAY) ORDER BY v.next_date ASC /select逻辑说明BETWEEN包含边界CURDATE()只取日期部分避免时间戳干扰。参数说明INTERVAL 7 DAY里的 7 可以改成配置项比如从application.yml读pet.vaccine.remind-days方便不同门店调整。查出来的结果可以直接推给前端做提醒列表也可以接短信或邮件但短信接口涉及第三方费用课程设计阶段用页面提醒就够了。3.3 增删改查的四个接口与参数校验宠物管理系统的增删改查不是简单调 Mapper每个操作都要加校验。新增宠物时owner_id必须存在pet_name不能为空birth_date不能晚于今天。修改时如果宠物已经有关联的寄养记录不允许直接删除只能标记为「已归档」。下面是一个 Controller 层的片段。PostMapping(/pet/add) public Result addPet(RequestBody Valid Pet pet) { // 校验主人是否存在 Owner owner ownerMapper.selectById(pet.getOwnerId()); if (owner null) { return Result.fail(主人不存在); } petMapper.insert(pet); return Result.success(添加成功); }逻辑说明Valid配合实体类上的NotBlank、Past等注解做基础校验业务校验放在 Service 或 Controller 里。参数说明Result是统一返回包装类包含code、msg、data三个字段前端好处理。删除接口建议做成逻辑删除在表里加is_deleted字段查询时默认过滤这样误删了还有后悔药。4. 避坑与排查从启动报错到数据对不上4.1 启动报Invalid bound statement (not found)现象Spring Boot 启动正常一调 Mapper 方法就报这个错。原因通常是 XML 文件没被扫描到或者namespace写错。解决检查application.yml里mybatis.mapper-locations是否指向classpath:mapper/*.xml检查 XML 的namespace是否和 Mapper 接口全限定名完全一致包括大小写。如果用的是 Maven确认src/main/resources下的 XML 被正确打包。4.2 中文乱码数据库、连接、页面三处都要查现象宠物名存进去变成???。原因可能是数据库字符集不是utf8mb4或者 JDBC URL 没加characterEncodingutf8。解决建库时指定utf8mb4连接串写成jdbc:mysql://localhost:3306/pet_manage?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai。如果页面还乱码检查返回头的Content-Type是否带charsetUTF-8。4.3 日期字段差一天时区在捣鬼现象前端传2024-05-01数据库存成2024-04-30。原因通常是 JDBC 连接没指定时区或者实体类用了java.util.Date而数据库是DATE。解决连接串加serverTimezoneAsia/Shanghai实体类日期字段优先用LocalDate和LocalDateTimeMyBatis 从 3.4.5 起已原生支持。4.4 外键约束导致删除失败现象删除主人时报Cannot delete or update a parent row。原因是有宠物还关联着这个主人。解决要么先删宠物再删主人要么在数据库层面设置ON DELETE CASCADE要么在业务层做逻辑删除。课程设计里建议用逻辑删除避免级联删除把诊疗记录也清掉。4.5 分页查询总数不对现象列表只显示 10 条但总数显示 100 条。原因通常是分页插件只对查询语句加了LIMIT没执行 count 查询或者 count 查询里带了ORDER BY导致效率低。解决用 PageHelper 时PageHelper.startPage(pageNum, pageSize)后面紧跟的查询才会被分页count 由插件自动生成。如果手写分页count 语句要去掉ORDER BY。5. 论文与源码怎么讲清楚从 ER 图到测试用例的落地技巧5.1 论文框架别从「绪论」硬憋先画三张图写论文最卡的是第一章。我的习惯是先画 ER 图、系统架构图、核心业务流程图这三张图一出来需求分析和数据库设计两章就有了骨架。ER 图里把owner、pet、boarding、vaccine四个实体的属性和关系标清楚一对多关系用 1:N 标注。架构图就画 Controller、Service、Mapper、MySQL 四层旁边标注每层职责。流程图重点画寄养从入住到结算的完整路径包括异常分支比如「提前离店」。图不要用花哨工具draw.io 或 ProcessOn 导出 PNG 插入 Word 就行关键是字段名和代码里一致。5.2 测试用例表比截图更有说服力论文里的「系统测试」章节不要只贴几张页面截图。做一个测试用例表包含用例编号、测试功能、输入数据、预期结果、实际结果、是否通过。比如「寄养费用计算」这条输入入住 2024-05-01、离店 2024-05-04、单价 50预期 150 元实际 150 元通过。再补一条边界用例当天入住当天离店预期 50 元。这样导师一看就知道你真的跑过不是纯写文档。用例编号测试功能输入数据预期结果实际结果TC-01新增宠物主人ID1宠物名豆豆添加成功添加成功TC-02寄养计费5月1日入住5月4日离店单价50150元150元TC-03疫苗提醒疫苗到期日今天3天出现在提醒列表出现在提醒列表TC-04删除主人主人ID1有宠物关联提示先处理宠物提示先处理宠物5.3 源码整理别把target和.idea一起打包最后交付源码时把target、.idea、*.iml、node_modules这些目录排除掉只留src、pom.xml、application.yml、sql脚本和README.md。README 里写清楚JDK 版本、MySQL 版本、导入 SQL 的顺序、启动命令、默认端口。如果附带视频视频里重点演示「从空库到跑通第一个查询」的过程不要从头到尾念代码。论文和源码的对应关系在 README 里列一个表论文第几章对应哪个包或哪个类导师查重和答辩时都能快速定位。我自己的习惯是每次改完代码先跑一遍 TC-01 到 TC-04 这四条用例确认核心链路没断再动其他功能。这套东西不难难的是字段命名统一、日期处理不拍脑袋、删除之前想清楚关联。希望帮到你。本文还有配套的精品资源点击获取