Flyway简介
Flyway简介
总结:Flyway可以很方便的帮我们完成数据库部署和增量升级,很有用,但是版本回滚操作并不给力~~~
1、简介
1.1、Flyway是什么
Flyway是一款数据库迁移(migration)工具。简单点说,就是在你部署应用的时候,帮你执行数据库脚本的工具。Flyway支持SQL和Java两种类型的脚本,你可以将脚本打包到应用程序中,在应用程序启动时,由Flyway来管理这些脚本的执行,这些脚本被Flyway称之为migration。
就目前而言,我们部署应用的流程大概是这样的:
- 开发人员将应用程序打包、按顺序汇总并整理数据库升级脚本
- DBA拿到数据库升级脚本检查、备份、执行,以完成数据库升级
- 应部署人员拿到应用部署包,备份、替换,以完成应用程序升级
引入Flyway之后的应用部署流程大概是这样的:
- 开发人员将应用程序打包
- 应部署人员拿到应用部署包,备份、替换,以完成应用程序升(Flyway将自动执行升级/备份脚本)
1.1、Flyway如何工作
最简单的理解方式是:简单我们在一个空数据库上部署集成了Flyway的应用:
Flyway将在这个空数据中创建一张表,用于记录migration的执行情况,表名称默认为:flyway_schema_histor,老版本的表名称:schema_version
紧接着,Flyway根据表中的记录决定是否执行应用程序包中提供的migration
最后将执行结果写入flyway_schema_histor并校验执行结果
下次版本迭代时,提供新的migration,会根据flyway_schema_histor的记录执行新migration
2、核心概念
2.1、Migration
Flyway将每一个数据库脚本称之为:migrations,flyway支持三种类型的migration:
- Versioned migrations:最常用的migration,可以简单的理解为数据库升级脚本
- Undo migrations:数据库版本回退脚本,需要Pro版本,忽略,而且使用过程存在较大风险,undo操作目前只能通过plugin或者command-line来执行
- Repeatable migrations:可重复执行的migration,例如create or replace脚本,当脚本checksums改变时会重新执行
每个migration支持两种编写方式:
- Java:通过实现
org.flywaydb.core.api.migration.jdbc.JdbcMigratio
接口来创建一个Java migration,也就是通过JDBC来执行SQL,对于类是CLOB或者BOLB这种不方便在SQL中实现的脚本比较有用,例如:
package db.migration;
import org.flywaydb.core.api.migration.jdbc.JdbcMigration;
import java.sql.Connection;
import java.sql.PreparedStatement;
/**
* Example of a Java-based migration.
*/
public class V1_2__Another_user implements JdbcMigration {
public void migrate(Connection connection) throws Exception {
PreparedStatement statement = connection.prepareStatement("INSERT INTO test_user (name) VALUES ('Obelix')");
try {
statement.execute();
} finally {
statement.close();
}
}
}
- SQL:简单的SQL脚本文件,例如:
/* Single line comment */
CREATE TABLE test_user (
name VARCHAR(25) NOT NULL,
PRIMARY KEY(name)
);
/*
Multi-line
comment
*/
-- Placeholder
INSERT INTO ${tableName} (name) VALUES ('Mr. T');
所有的migration都需要遵守命名规范:
确保版本号唯一,flyway按照版本号顺序执行。repeatable没有版本号,因为repeatable migrations会在内容改变时重复执行
默认情况下,flyway会将单个migration放在一个事物里执行,也可以通过配置将所有migration放在同一个事物里执行,感觉用处不大,这里就不介绍了~
2.2、Callbacks
Flyway在执行migrations时提供了一些列的hook,使你可以在执行过程中加入额外的操作:
这些hook均执行SQL和Java类型的migrations,只需要将migration的名称以hook名称开头即可,例如:beforeMigrate.sql
、beforeEachMigrate.sql
、 beforeRepair__vacuum.sql
,Java类型的hook需要实现接口:org.flywaydb.core.api.callback.Callback
2.3、Error Handlers
需要Flyway Pro版本,忽略,参考链接:https://flywaydb.org/documentation/errorhandlers
2.4、Dry Runs
需要Flyway Pro版本,忽略,参考链接:https://flywaydb.org/documentation/dryruns
3、使用事例
3.1、集成Spring Boot
- build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.0.2.RELEASE'
}
group 'com.chenlei'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.0.2.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: '2.0.2.RELEASE'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.46'
compile group: 'org.flywaydb', name: 'flyway-core', version: '5.1.1'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
- application.yml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://192.168.119.123:3306/flyway?useUnicode=true&characterEncoding=utf8&useSSL=false
username: flyway
password: Flyway@1234
driver-class-name: com.mysql.jdbc.Driver
flyway:
locations: classpath:com/chenlei/flyway/db/mysql
3.2、Gradle插件
- build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.0.2.RELEASE'
id "org.flywaydb.flyway" version "5.1.1"
}
flyway {
url = 'jdbc:mysql://192.168.119.123:3306/flyway?useUnicode=true&characterEncoding=utf-8&useSSL=false'
user = 'flyway'
password = 'aaa@qq.com'
locations = ['classpath:com/chenlei/flyway/db/mysql']
encoding = 'UTF-8'
}
group 'com.chenlei'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.0.2.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: '2.0.2.RELEASE'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.46'
compile group: 'org.flywaydb', name: 'flyway-core', version: '5.1.1'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
注意:
- Clean会将数据库schema下的所有内容清空,谨慎执行
- Baseline的版本号和migration冲突时,migration不会执行
- Repeatable仅在check sum发送改变时会再次执行,Java migration需要实现
org.flywaydb.core.api.migration.MigrationInfoProvider
接口 - Gradle查询无法执行实现
org.flywaydb.core.api.migration.spring.SpringJdbcMigration
接口的migrations,只能是实现org.flywaydb.core.api.migration.jdbc.JdbcMigration
的migrations - Undo需要Pro版本
Maven插件与此类似~