16 KiB
Tuoheng Device 模块说明文档
目录
1. 模块概述
tuoheng-device 是设备管理模块,负责设备相关的业务逻辑处理。
核心功能:
- 设备信息管理
- 数据库表自动管理(基于 Flyway)
- RESTful API 接口
技术栈:
- Spring Boot 3.x
- MyBatis
- Flyway(数据库版本管理)
- Nacos(配置中心)
2. Flyway 数据库迁移工具使用指南
2.1 什么是 Flyway
Flyway 是一个开源的数据库版本管理工具,它可以:
- ✅ 自动管理数据库表的创建和更新
- ✅ 记录数据库变更历史
- ✅ 支持多环境部署(开发、测试、生产)
- ✅ 确保数据库结构的一致性
- ✅ 支持回滚和版本控制
为什么使用 Flyway?
- 自动化:应用启动时自动检查并执行数据库变更
- 版本化:每次变更都有明确的版本号,便于追踪
- 安全性:不会删除表或数据,只会增量更新
- 团队协作:避免手动执行 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 目录下已有的脚本,确定下一个版本号。
# 假设已有脚本:
V1__Create_device_temp_table.sql
V2__Add_device_name_column.sql
# 新脚本版本号应为:V3
步骤 2:创建迁移脚本
在 db/migration 目录下创建新文件:V3__Create_device_info_table.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 会自动:
- 检测到新的迁移脚本 V3
- 执行 SQL 创建表
- 记录执行历史到
flyway_schema_history表
步骤 4:验证
查询数据库确认表已创建:
SHOW TABLES LIKE 'device_info';
SELECT * FROM flyway_schema_history WHERE version = '3';
2.6 修改表结构操作
场景 1:添加新字段
步骤 1:创建迁移脚本
文件名:V4__Add_device_location_column.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
-- ============================================================
-- 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
-- ============================================================
-- 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
-- ============================================================
-- 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
-- 创建设备类型表
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
-- 插入初始设备类型数据
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
-- 步骤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 注意事项
⚠️ 重要规则
-
版本号必须递增
- ❌ 不能修改已执行的脚本
- ❌ 不能删除已执行的脚本
- ✅ 只能创建新的版本脚本
-
脚本只执行一次
- Flyway 会记录已执行的脚本
- 相同版本号的脚本不会重复执行
- 如果需要修改,必须创建新版本
-
不要修改已执行的脚本
- 已执行的脚本有 checksum 校验
- 修改会导致校验失败,应用启动报错
- 如需修改,创建新的迁移脚本
-
使用事务
- 每个迁移脚本在一个事务中执行
- 如果执行失败,会自动回滚
- 确保脚本的原子性
-
测试脚本
- 在开发环境先测试脚本
- 确认无误后再部署到生产环境
-
备份数据
- 执行重要变更前备份数据库
- 特别是删除字段或表的操作
2.9 常见问题
Q1: 如何查看 Flyway 执行历史?
SELECT * FROM flyway_schema_history ORDER BY installed_rank;
Q2: 脚本执行失败怎么办?
情况 1:脚本语法错误
- 查看应用启动日志,找到错误信息
- 修复 SQL 语法错误
- 删除
flyway_schema_history表中失败的记录:DELETE FROM flyway_schema_history WHERE success = 0; - 重启应用
情况 2:脚本逻辑错误(如字段已存在)
- 创建新的修复脚本(版本号递增)
- 在新脚本中使用
IF NOT EXISTS或IF EXISTS语句 - 重启应用
Q3: 如何跳过某个版本的脚本?
不推荐跳过脚本! 如果确实需要:
-
手动在
flyway_schema_history表中插入记录: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); -
重启应用
Q4: 如何在多环境中使用 Flyway?
Flyway 会自动适配不同环境:
- 开发环境:本地数据库,自动创建表
- 测试环境:测试数据库,执行相同的迁移脚本
- 生产环境:生产数据库,执行相同的迁移脚本
关键点:
- 所有环境使用相同的迁移脚本
- Flyway 会根据
flyway_schema_history表判断哪些脚本需要执行
Q5: 如何禁用 Flyway?
在 Nacos 配置中添加:
spring:
flyway:
enabled: false
Q6: 迁移脚本可以包含多个 SQL 语句吗?
可以!一个脚本可以包含多个 SQL 语句,用分号分隔:
CREATE TABLE table1 (...);
CREATE TABLE table2 (...);
INSERT INTO table1 VALUES (...);
Q7: 如何回滚数据库变更?
Flyway 社区版不支持自动回滚。如需回滚:
-
方式 1:创建回滚脚本
-- V11__Rollback_device_status_change.sql ALTER TABLE device_info DROP COLUMN new_column; -
方式 2:手动回滚
- 备份数据库
- 手动执行回滚 SQL
- 删除
flyway_schema_history中的记录
3. 开发工作流程
3.1 新增表的完整流程
-
创建 Flyway 迁移脚本
- 文件:
db/migration/Vx__Create_xxx_table.sql
- 文件:
-
创建实体类
- 文件:
domain/XxxEntity.java
- 文件:
-
创建 Mapper 接口
- 文件:
mapper/XxxMapper.java
- 文件:
-
创建 Mapper XML
- 文件:
resources/mapper/device/XxxMapper.xml
- 文件:
-
创建 Service 接口和实现
- 文件:
service/IXxxService.java - 文件:
service/impl/XxxServiceImpl.java
- 文件:
-
创建 Controller
- 文件:
controller/XxxController.java
- 文件:
-
重启应用测试
3.2 修改表结构的完整流程
-
创建 Flyway 迁移脚本
- 文件:
db/migration/Vx__Modify_xxx_table.sql
- 文件:
-
更新实体类
- 添加或修改字段
-
更新 Mapper XML
- 更新 resultMap 和 SQL 语句
-
更新 Service 和 Controller
- 根据需要调整业务逻辑
-
重启应用测试
4. 最佳实践
4.1 脚本编写建议
-
使用 IF NOT EXISTS / IF EXISTS
CREATE TABLE IF NOT EXISTS table_name (...); ALTER TABLE table_name ADD COLUMN IF NOT EXISTS column_name VARCHAR(100); -
添加详细注释
-- 为什么要做这个变更 -- 影响范围 -- 注意事项 -
一个脚本只做一件事
- ✅ V1__Create_device_table.sql
- ✅ V2__Add_device_index.sql
- ❌ V1__Create_and_modify_everything.sql
-
使用事务安全的语句
- DDL 语句在 MySQL 中会自动提交
- 谨慎使用 DROP、TRUNCATE 等危险操作
4.2 团队协作建议
-
版本号管理
- 团队成员协调版本号,避免冲突
- 使用 Git 管理迁移脚本
-
代码审查
- 迁移脚本必须经过 Code Review
- 特别关注 DROP、DELETE 等危险操作
-
文档记录
- 在脚本中添加详细的变更说明
- 更新本文档记录重要变更
5. 参考资料
6. 联系方式
如有问题,请联系:
- 技术负责人:xxx
- 邮箱:xxx@example.com
最后更新时间: 2026-01-15