Flyway管理数据库表结构
一、为什么要用Flyway
Flyway 是一款开源的数据库版本管理工具。Flyway 可以独立于应用实现管理并跟踪数据库变更,支持数据库版本自动升级。
说白了就是,每一次数据库表结构变更时,把修改的语句交给flyway去执行,不再交由人去手动执行,避免了因为人手动执行导致的错误。
二、如何使用
首先是搭建项目,这里展示flyway + spring boot+ mysql的示例。
2.1 gradle配置参考
plugins {
id 'org.springframework.boot' version '2.6.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.tosee'
sourceCompatibility = '11'
repositories {
mavenLocal()
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
mavenCentral()
}
dependencies {
implementation 'com.zaxxer:HikariCP:5.0.0'
implementation 'mysql:mysql-connector-java:8.0.27'
// 引入flyway
implementation 'org.flywaydb:flyway-core:7.2.1'
implementation("com.alibaba.nacos:nacos-client:2.0.3")
implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.0'
implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2021.1'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
}
dependencyManagement {
imports {
mavenBom "org.springframework.boot:spring-boot-dependencies:2.6.2"
mavenBom "org.springframework.cloud:spring-cloud-dependencies:2021.0.0"
mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:2.2.0.RELEASE"
}
}
bootJar {
mainClass.set("xxxxxx")
}
2.2 配置数据变更文件
在src/main/resources创建 db\数据库名 的文件夹,有多个库就建多个。
在需要变更的数据库的文件夹里创建sql文件,具体格式如下:
- V[version]__[name].sql: V开头的文件只会被flyway执行一次
- R__[name].sql: R开头的文件每次flyway运行时,都会被执行
V开头的SQL执行优先级要比R开头的SQL优先级高
2.2.1 示例
V1.0.0__create_table.sql
create database `app_device`;
use `app_device`;
-- 设备
CREATE TABLE `device`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`sn` varchar(128) NOT NULL,
`device_no` varchar(64) NOT NULL,
`deleted` tinyint(2) NOT NULL DEFAULT '0' COMMENT '删除状态 0未删除 1已删除',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `deleted_key` (`deleted`),
KEY `device_no_key` (`device_no`),
KEY `sn_key` (`sn`)
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
2.3 配置Flyway
// dbNameMap从配置文件里读取自定义的配置
// key是数据库别名
// value是数据库名
dbNameMap.forEach((key, value) -> {
// blackList从配置文件里读取自定义的配置
// 如果在黑名单里,就不执行操作
if (blackList != null && !blackList.isEmpty() && dbNameMap.containsKey(key)) {
return;
}
// 配置datasource
HikariDataSource dataSource = new HikariDataSource();
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setJdbcUrl("jdbc:mysql://" + address + ":" + port + "/" + value + "?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai");
Flyway.configure()
.dataSource(dataSource)
// 配置数据库变更sql的文件所在目录
.locations("classpath:db/" + key)
// 配置编码
.encoding(StandardCharsets.UTF_8)
// 忽略丢失的migration文件
.ignoreMissingMigrations(true)
// 当迁移发现数据库非空且存在没有元数据的表时,自动执行基准迁移,新建schema_version表
.baselineOnMigrate(true)
// 是否验证migration文件
.validateMigrationNaming(true)
// 禁用flyway的clean操作,clean会清除掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等
.cleanDisabled(true)
// 是否可以无须执行
.outOfOrder(false)
// 版本化SQL迁移文件名前缀,可以不用配置,默认就是V
.sqlMigrationPrefix("V")
// 配置扩展名,可以不用配置,默认就是.sql
.sqlMigrationSuffixes(".sql")
// version与name的分隔符,可以不用配置,默认就是__
.sqlMigrationSeparator("__")
.load()
.migrate();
});
baselineOnMigrate
如果flyway 不是项目初期引入,而是在数据库已有表的情况下引入的
必须设置 baselineOnMigrate true,baselineVersion 1.0.0
设置该配置启动项目后,flyway 就会在数据库中创建 flyway_schema_history 表
并且会往该表中插入一条 version = 1.0.0 的建表记录
如果迁移数据有 V1.0.0__ 开头的文件扫描文件会忽略该文件不执行迁移
Loading...