
1. 项目背景与技术选型解析健身房管理系统作为传统服务行业数字化转型的典型场景面临着会员信息管理、课程预约、财务统计等多方面的业务挑战。这套基于SpringBoot2Vue3MyBatis-PlusMySQL8.0的技术方案正是针对这些痛点设计的全栈解决方案。技术栈的深层考量后端选择Spring Boot 2.7.x版本而非最新的3.x是出于企业级稳定性的考虑该版本具有LTS长期支持且与MyBatis-Plus 3.5.x完美兼容Vue 3的组合式API相比选项式API更适合复杂的前端状态管理特别是在需要实时更新会员课程预约状态的场景MySQL 8.0的JSON字段类型完美适配健身房的动态会员档案存储需求其窗口函数也简化了销售业绩分析报表的生成实际开发中发现MyBatis-Plus 3.5.3版本与MySQL 8.0.28的批量插入存在兼容性问题需在配置中添加rewriteBatchedStatementstrue参数2. 核心数据库设计与优化2.1 关键表结构设计会员核心表采用纵向分表策略将高频访问的基础信息与低频使用的健康档案分离CREATE TABLE member_basic ( member_id BIGINT PRIMARY KEY AUTO_INCREMENT, card_no VARCHAR(20) UNIQUE NOT NULL COMMENT 会员卡号, member_name VARCHAR(50) NOT NULL, gender TINYINT DEFAULT 0 COMMENT 0未知 1男 2女, phone VARCHAR(20) UNIQUE NOT NULL, avatar VARCHAR(255) DEFAULT NULL, card_status TINYINT DEFAULT 1 COMMENT 0停用 1正常 2冻结, register_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci; CREATE TABLE member_health ( id BIGINT PRIMARY KEY AUTO_INCREMENT, member_id BIGINT NOT NULL, height DECIMAL(5,2) COMMENT 单位cm, weight DECIMAL(5,2) COMMENT 单位kg, blood_type VARCHAR(10), medical_history JSON COMMENT 病史记录, FOREIGN KEY (member_id) REFERENCES member_basic(member_id) ) ENGINEInnoDB;2.2 性能优化实践课程预约表需要特殊索引设计应对高峰时段的并发预约-- 复合索引优化查询 CREATE INDEX idx_course_schedule ON course_booking(course_id, schedule_time); -- 解决死锁问题的隔离级别调整 SET GLOBAL transaction_isolationREAD-COMMITTED;踩坑记录MySQL 8.0默认的caching_sha2_password认证方式会导致部分客户端连接失败需在初始化时执行ALTER USER root% IDENTIFIED WITH mysql_native_password BY yourpassword;3. 后端关键实现细节3.1 三层架构的落地实现采用DDD领域驱动设计思想对传统三层架构进行改良src/main/java/com/gym/ ├── application # 应用层 │ ├── command # CQRS命令 │ └── query # 查询服务 ├── domain # 领域层 │ ├── model # 聚合根 │ └── service # 领域服务 └── infrastructure # 基础设施层 ├── dao # MyBatis-Plus映射 └── cache # Redis集成会员状态变更的典型领域服务示例public class MemberCardService { Transactional public void freezeMember(Long memberId, String reason) { Member member memberRepository.selectById(memberId); if (member.isFrozen()) { throw new BusinessException(会员已处于冻结状态); } member.freeze(); memberRepository.updateById(member); // 事件发布 domainEventPublisher.publish(new MemberFrozenEvent(memberId, reason)); } }3.2 支付模块的防重处理利用Redis原子操作实现支付防重public PaymentResult handlePayment(PaymentRequest request) { String lockKey payment: request.getOrderNo(); // 使用SETNX实现分布式锁 Boolean locked redisTemplate.opsForValue() .setIfAbsent(lockKey, 1, 5, TimeUnit.MINUTES); if (!locked) { throw new BusinessException(支付处理中请勿重复提交); } try { // 实际支付逻辑 return paymentService.process(request); } finally { redisTemplate.delete(lockKey); } }4. 前端工程化实践4.1 Vue3组合式API的典型应用课程表组件采用