# Tuoheng Device 模块说明文档 ## 目录 - [1. 模块概述](#1-模块概述) - [2. Flyway 数据库迁移工具使用指南](#2-flyway-数据库迁移工具使用指南) - [2.1 什么是 Flyway](#21-什么是-flyway) - [2.2 Flyway 工作原理](#22-flyway-工作原理) - [2.3 目录结构](#23-目录结构) - [2.4 迁移脚本命名规则](#24-迁移脚本命名规则) - [2.5 新增表操作](#25-新增表操作) - [2.6 修改表结构操作](#26-修改表结构操作) - [2.7 常见场景示例](#27-常见场景示例) - [2.8 注意事项](#28-注意事项) - [2.9 常见问题](#29-常见问题) --- ## 1. 模块概述 `tuoheng-device` 是设备管理模块,负责设备相关的业务逻辑处理。 **核心功能:** - 设备信息管理 - 数据库表自动管理(基于 Flyway) - RESTful API 接口 **技术栈:** - Spring Boot 3.x - MyBatis - Flyway(数据库版本管理) - Nacos(配置中心) --- ## 2. Flyway 数据库迁移工具使用指南 ### 2.1 什么是 Flyway Flyway 是一个开源的数据库版本管理工具,它可以: - ✅ 自动管理数据库表的创建和更新 - ✅ 记录数据库变更历史 - ✅ 支持多环境部署(开发、测试、生产) - ✅ 确保数据库结构的一致性 - ✅ 支持回滚和版本控制 **为什么使用 Flyway?** 1. **自动化**:应用启动时自动检查并执行数据库变更 2. **版本化**:每次变更都有明确的版本号,便于追踪 3. **安全性**:不会删除表或数据,只会增量更新 4. **团队协作**:避免手动执行 SQL 导致的环境不一致 --- ### 2.2 Flyway 工作原理 #### 启动流程 ``` 应用启动 ↓ Flyway 初始化 ↓ 检查数据库中是否存在 flyway_schema_history 表 ↓ ├─ 不存在 → 创建 flyway_schema_history 表 └─ 存在 → 读取已执行的迁移记录 ↓ 扫描 db/migration 目录下的 SQL 脚本 ↓ 对比版本号,找出未执行的脚本 ↓ 按版本号顺序执行未执行的脚本 ↓ 记录执行结果到 flyway_schema_history 表 ↓ 应用启动完成 ``` #### 版本管理表 Flyway 会自动创建 `flyway_schema_history` 表来记录迁移历史: | 字段 | 说明 | |------|------| | installed_rank | 执行顺序 | | version | 版本号(如 1, 2, 3) | | description | 描述信息 | | type | 类型(SQL) | | script | 脚本文件名 | | checksum | 校验和 | | installed_by | 执行用户 | | installed_on | 执行时间 | | execution_time | 执行耗时 | | success | 是否成功 | --- ### 2.3 目录结构 ``` tuoheng-device/ └── src/ └── main/ └── resources/ └── db/ └── migration/ # Flyway 迁移脚本目录 ├── V1__Create_device_temp_table.sql ├── V2__Add_device_name_column.sql ├── V3__Add_device_status_column.sql └── ... ``` **重要说明:** - 所有迁移脚本必须放在 `db/migration` 目录下 - Flyway 会自动扫描该目录下的所有 SQL 文件 - 脚本按版本号顺序执行 --- ### 2.4 迁移脚本命名规则 #### 命名格式 ``` V{版本号}__{描述}.sql ``` **格式说明:** - `V` - 固定前缀(大写字母 V) - `{版本号}` - 数字版本号,必须递增(如 1, 2, 3 或 1.0, 1.1, 2.0) - `__` - 两个下划线分隔符 - `{描述}` - 英文描述,使用下划线连接单词 - `.sql` - 文件扩展名 #### 命名示例 ✅ **正确示例:** ``` V1__Create_device_temp_table.sql V2__Add_device_name_column.sql V3__Add_device_status_index.sql V4__Update_device_type_enum.sql V1.0__Initial_schema.sql V1.1__Add_user_table.sql V2.0__Refactor_device_structure.sql ``` ❌ **错误示例:** ``` v1__create_table.sql # V 必须大写 V1_create_table.sql # 只有一个下划线 V1__创建表.sql # 不能使用中文 create_table.sql # 缺少版本号前缀 V1.sql # 缺少描述 ``` --- ### 2.5 新增表操作 #### 场景:创建一个新表 **步骤 1:确定版本号** 查看 `db/migration` 目录下已有的脚本,确定下一个版本号。 ```bash # 假设已有脚本: V1__Create_device_temp_table.sql V2__Add_device_name_column.sql # 新脚本版本号应为:V3 ``` **步骤 2:创建迁移脚本** 在 `db/migration` 目录下创建新文件:`V3__Create_device_info_table.sql` ```sql -- ============================================================ -- Flyway Migration Script -- ============================================================ -- Version: V3 -- Description: Create device_info table -- Author: your_name -- Date: 2026-01-15 -- ============================================================ -- 创建设备信息表 CREATE TABLE IF NOT EXISTS device_info ( id VARCHAR(64) NOT NULL COMMENT '主键ID', device_name VARCHAR(100) NOT NULL COMMENT '设备名称', device_type VARCHAR(50) COMMENT '设备类型', status TINYINT DEFAULT 0 COMMENT '状态:0-离线 1-在线', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (id), INDEX idx_device_name (device_name), INDEX idx_status (status) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='设备信息表'; ``` **步骤 3:重启应用** 重启应用后,Flyway 会自动: 1. 检测到新的迁移脚本 V3 2. 执行 SQL 创建表 3. 记录执行历史到 `flyway_schema_history` 表 **步骤 4:验证** 查询数据库确认表已创建: ```sql SHOW TABLES LIKE 'device_info'; SELECT * FROM flyway_schema_history WHERE version = '3'; ``` --- ### 2.6 修改表结构操作 #### 场景 1:添加新字段 **步骤 1:创建迁移脚本** 文件名:`V4__Add_device_location_column.sql` ```sql -- ============================================================ -- Flyway Migration Script -- ============================================================ -- Version: V4 -- Description: Add location column to device_info table -- Author: your_name -- Date: 2026-01-15 -- ============================================================ -- 添加位置字段 ALTER TABLE device_info ADD COLUMN location VARCHAR(200) COMMENT '设备位置' AFTER device_type; ``` **步骤 2:重启应用** Flyway 会自动执行 ALTER TABLE 语句。 --- #### 场景 2:修改字段类型 **步骤 1:创建迁移脚本** 文件名:`V5__Modify_device_name_length.sql` ```sql -- ============================================================ -- Flyway Migration Script -- ============================================================ -- Version: V5 -- Description: Modify device_name column length -- Author: your_name -- Date: 2026-01-15 -- ============================================================ -- 修改设备名称字段长度 ALTER TABLE device_info MODIFY COLUMN device_name VARCHAR(200) NOT NULL COMMENT '设备名称'; ``` --- #### 场景 3:添加索引 **步骤 1:创建迁移脚本** 文件名:`V6__Add_device_type_index.sql` ```sql -- ============================================================ -- Flyway Migration Script -- ============================================================ -- Version: V6 -- Description: Add index on device_type column -- Author: your_name -- Date: 2026-01-15 -- ============================================================ -- 添加设备类型索引 CREATE INDEX idx_device_type ON device_info(device_type); ``` --- #### 场景 4:删除字段(谨慎操作) **步骤 1:创建迁移脚本** 文件名:`V7__Drop_device_location_column.sql` ```sql -- ============================================================ -- Flyway Migration Script -- ============================================================ -- Version: V7 -- Description: Drop location column from device_info table -- Author: your_name -- Date: 2026-01-15 -- ============================================================ -- 删除位置字段(谨慎操作,确保该字段不再使用) ALTER TABLE device_info DROP COLUMN location; ``` ⚠️ **警告:** 删除字段会导致数据丢失,操作前务必确认! --- ### 2.7 常见场景示例 #### 示例 1:创建多个表 文件名:`V8__Create_multiple_tables.sql` ```sql -- 创建设备类型表 CREATE TABLE IF NOT EXISTS device_type ( id VARCHAR(64) NOT NULL COMMENT '主键ID', type_name VARCHAR(50) NOT NULL COMMENT '类型名称', type_code VARCHAR(20) NOT NULL COMMENT '类型编码', PRIMARY KEY (id), UNIQUE KEY uk_type_code (type_code) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='设备类型表'; -- 创建设备日志表 CREATE TABLE IF NOT EXISTS device_log ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', device_id VARCHAR(64) NOT NULL COMMENT '设备ID', log_type VARCHAR(20) COMMENT '日志类型', log_content TEXT COMMENT '日志内容', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (id), INDEX idx_device_id (device_id), INDEX idx_create_time (create_time) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='设备日志表'; ``` --- #### 示例 2:插入初始数据 文件名:`V9__Insert_initial_device_types.sql` ```sql -- 插入初始设备类型数据 INSERT INTO device_type (id, type_name, type_code) VALUES ('1', '无人机', 'DRONE'), ('2', '地面站', 'GROUND_STATION'), ('3', '传感器', 'SENSOR') ON DUPLICATE KEY UPDATE type_name = VALUES(type_name); ``` --- #### 示例 3:修改表结构并迁移数据 文件名:`V10__Migrate_device_status_to_enum.sql` ```sql -- 步骤1:添加新字段 ALTER TABLE device_info ADD COLUMN status_new ENUM('OFFLINE', 'ONLINE', 'MAINTENANCE') DEFAULT 'OFFLINE' COMMENT '设备状态' AFTER status; -- 步骤2:迁移数据 UPDATE device_info SET status_new = CASE WHEN status = 0 THEN 'OFFLINE' WHEN status = 1 THEN 'ONLINE' ELSE 'OFFLINE' END; -- 步骤3:删除旧字段 ALTER TABLE device_info DROP COLUMN status; -- 步骤4:重命名新字段 ALTER TABLE device_info CHANGE COLUMN status_new status ENUM('OFFLINE', 'ONLINE', 'MAINTENANCE') DEFAULT 'OFFLINE' COMMENT '设备状态'; ``` --- ### 2.8 注意事项 #### ⚠️ 重要规则 1. **版本号必须递增** - ❌ 不能修改已执行的脚本 - ❌ 不能删除已执行的脚本 - ✅ 只能创建新的版本脚本 2. **脚本只执行一次** - Flyway 会记录已执行的脚本 - 相同版本号的脚本不会重复执行 - 如果需要修改,必须创建新版本 3. **不要修改已执行的脚本** - 已执行的脚本有 checksum 校验 - 修改会导致校验失败,应用启动报错 - 如需修改,创建新的迁移脚本 4. **使用事务** - 每个迁移脚本在一个事务中执行 - 如果执行失败,会自动回滚 - 确保脚本的原子性 5. **测试脚本** - 在开发环境先测试脚本 - 确认无误后再部署到生产环境 6. **备份数据** - 执行重要变更前备份数据库 - 特别是删除字段或表的操作 --- ### 2.9 常见问题 #### Q1: 如何查看 Flyway 执行历史? ```sql SELECT * FROM flyway_schema_history ORDER BY installed_rank; ``` --- #### Q2: 脚本执行失败怎么办? **情况 1:脚本语法错误** 1. 查看应用启动日志,找到错误信息 2. 修复 SQL 语法错误 3. 删除 `flyway_schema_history` 表中失败的记录: ```sql DELETE FROM flyway_schema_history WHERE success = 0; ``` 4. 重启应用 **情况 2:脚本逻辑错误(如字段已存在)** 1. 创建新的修复脚本(版本号递增) 2. 在新脚本中使用 `IF NOT EXISTS` 或 `IF EXISTS` 语句 3. 重启应用 --- #### Q3: 如何跳过某个版本的脚本? **不推荐跳过脚本!** 如果确实需要: 1. 手动在 `flyway_schema_history` 表中插入记录: ```sql INSERT INTO flyway_schema_history (installed_rank, version, description, type, script, checksum, installed_by, installed_on, execution_time, success) VALUES (999, '5', 'Skipped migration', 'SQL', 'V5__Skipped.sql', 0, 'manual', NOW(), 0, 1); ``` 2. 重启应用 --- #### Q4: 如何在多环境中使用 Flyway? Flyway 会自动适配不同环境: - **开发环境**:本地数据库,自动创建表 - **测试环境**:测试数据库,执行相同的迁移脚本 - **生产环境**:生产数据库,执行相同的迁移脚本 **关键点:** - 所有环境使用相同的迁移脚本 - Flyway 会根据 `flyway_schema_history` 表判断哪些脚本需要执行 --- #### Q5: 如何禁用 Flyway? 在 Nacos 配置中添加: ```yaml spring: flyway: enabled: false ``` --- #### Q6: 迁移脚本可以包含多个 SQL 语句吗? 可以!一个脚本可以包含多个 SQL 语句,用分号分隔: ```sql CREATE TABLE table1 (...); CREATE TABLE table2 (...); INSERT INTO table1 VALUES (...); ``` --- #### Q7: 如何回滚数据库变更? Flyway 社区版不支持自动回滚。如需回滚: 1. **方式 1:创建回滚脚本** ```sql -- V11__Rollback_device_status_change.sql ALTER TABLE device_info DROP COLUMN new_column; ``` 2. **方式 2:手动回滚** - 备份数据库 - 手动执行回滚 SQL - 删除 `flyway_schema_history` 中的记录 --- ## 3. 开发工作流程 ### 3.1 新增表的完整流程 1. **创建 Flyway 迁移脚本** - 文件:`db/migration/Vx__Create_xxx_table.sql` 2. **创建实体类** - 文件:`domain/XxxEntity.java` 3. **创建 Mapper 接口** - 文件:`mapper/XxxMapper.java` 4. **创建 Mapper XML** - 文件:`resources/mapper/device/XxxMapper.xml` 5. **创建 Service 接口和实现** - 文件:`service/IXxxService.java` - 文件:`service/impl/XxxServiceImpl.java` 6. **创建 Controller** - 文件:`controller/XxxController.java` 7. **重启应用测试** --- ### 3.2 修改表结构的完整流程 1. **创建 Flyway 迁移脚本** - 文件:`db/migration/Vx__Modify_xxx_table.sql` 2. **更新实体类** - 添加或修改字段 3. **更新 Mapper XML** - 更新 resultMap 和 SQL 语句 4. **更新 Service 和 Controller** - 根据需要调整业务逻辑 5. **重启应用测试** --- ## 4. 最佳实践 ### 4.1 脚本编写建议 1. **使用 IF NOT EXISTS / IF EXISTS** ```sql CREATE TABLE IF NOT EXISTS table_name (...); ALTER TABLE table_name ADD COLUMN IF NOT EXISTS column_name VARCHAR(100); ``` 2. **添加详细注释** ```sql -- 为什么要做这个变更 -- 影响范围 -- 注意事项 ``` 3. **一个脚本只做一件事** - ✅ V1__Create_device_table.sql - ✅ V2__Add_device_index.sql - ❌ V1__Create_and_modify_everything.sql 4. **使用事务安全的语句** - DDL 语句在 MySQL 中会自动提交 - 谨慎使用 DROP、TRUNCATE 等危险操作 --- ### 4.2 团队协作建议 1. **版本号管理** - 团队成员协调版本号,避免冲突 - 使用 Git 管理迁移脚本 2. **代码审查** - 迁移脚本必须经过 Code Review - 特别关注 DROP、DELETE 等危险操作 3. **文档记录** - 在脚本中添加详细的变更说明 - 更新本文档记录重要变更 --- ## 5. 参考资料 - [Flyway 官方文档](https://flywaydb.org/documentation/) - [Flyway 命名规范](https://flywaydb.org/documentation/concepts/migrations#naming) - [Spring Boot Flyway 集成](https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.data-initialization.migration-tool.flyway) --- ## 6. 联系方式 如有问题,请联系: - 技术负责人:xxx - 邮箱:xxx@example.com --- **最后更新时间:** 2026-01-15