Flyway入门
Flyway
Flyway 的中文文档近乎为零,英文文档也凤毛麟角,但它却是我们最理想的数据库版本管理工具,
特性
- 自动升级(自动发现更新项):Flyway 会将任意版本的数据库升级到最新版本。Flyway 可以脱离JVM 环境通过命令行执行,可以通过Ant 脚本执行,通过Maven 脚本执行(这样就可以在集成环境自动执行),并且可以在应用中执行(比如在应用启动时执行)。
- 规约优于配置:Flyway 有一套默认的规约,所以不需要修改任何配置就可以正常使用
- 既支持SQL 脚本,又支持Java 代码:可以使用SQL 脚本执行数据库更新,也可以使用Java 代码来进行一些高级数据升级操作
- 高可靠性:在集群环境下进行数据库升级是安全可靠的
- 支持清除已存在的库表结构:Flyway 可以清除已存在的库表结构,可以从零开始搭建您的库表结构,并管理您的数据库版本升级工作
- 支持失败修复。新的2.0 版本提供了repair 功能,用于解决数据库更新操作失败问题
运行
- cmd
1. 修改conf/flyway.properties 配置文件
2. 拷贝数据库jdbc 驱动jar 到jars/ 目录
3. 在sql/ 目录下创建配置好的sql 脚本文件目录路径,如flyway 默认的sql 文件路径为db/migration ,我们就需要在sql/ 目录下创建/db/migration 目录结构
4. 将数据库维护脚本放到创建好的sql 脚本文件目录中(维护脚本文件名需要遵循命名规范)
5. 在命令行执行命令(从flyway 安装目录开始执行)flyway init (初始化Flyway metadata )、flyway migrate(执行Flyway 升级操作)、flyway validate (校验Flyway 数据正确性)
2.maven
- mvn flyway:init
- mvn flyway:migrate
- mvn flyway:validate
<plugin>
<groupId>com.googlecode.flyway</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>3.1</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency>
</dependencies>
<configuration>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://localhost/flywaydemo?useUnicode=true&characterEncoding=utf-8</url>
<user>root</user>
<password></password>
<!-- 设置接受flyway进行版本管理的数据库,多个数据库以逗号分隔 -->
<schemas>flywaydemo</schemas>
<!-- 设置存放flyway metadata数据的表名 -->
<table>schema_version</table>
<!-- 设置flyway扫描sql升级脚本、java升级脚本的目录路径或包路径 -->
<locations>
<location>flyway/migrations</location>
<location>com.kedacom.flywaydemo.migrations</location>
</locations>
<!-- 设置sql脚本文件的编码 -->
<encoding>UTF-8</encoding>
<!-- 设置执行migrate操作之前的validation行为 -->
<validationMode>ALL</validationMode>
<!-- 设置当validation失败时的系统行为 -->
<validationErrorMode>FAIL</validationErrorMode>
</configuration>
33.
</plugin>
3.java
public class FlywayMigration {
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void migrate() {
Flyway flyway = new Flyway();
flyway.setDataSource(dataSource);
flyway.setSchemas("flywaydemo"); // 设置接受flyway进行版本管理的多个数据库
flyway.setTable("schema_version"); // 设置存放flyway metadata数据的表名
flyway.setLocations("flyway/migrations", "com.kedacom.flywaydemo.migrations"); // 设置flyway扫描sql升级脚本、java升级脚本的目录路径或包路径
flyway.setEncoding("UTF-8"); // 设置sql脚本文件的编码
flyway.setValidationMode(ValidationMode.ALL); // 设置执行migrate操作之前的validation行为
flyway.setValidationErrorMode(ValidationErrorMode.FAIL); // 设置当validation失败时的系统行为
flyway.migrate();
}
}
4.spring
<bean id="flywayMigration" class="com.kedacom.flywaydemo.FlywayMigration" init-method="migrate">
<property name="dataSource" ref="dataSource" />
</bean>
flywayMigration 这个bean 实例注入了一个数据源,Flyway 的所有操作将针对这个数据源进行;同时我们通过init-method 属性指定了Spring 在实例化该bean 以后,主动执行该bean的migrate 方法,而该方法内会执行Flyway 更新数据库的操作。至此,我们达到了在应用启动时,Spring 实例化上下文的时候,在Spring 实例化flywayMigration 这个bean 的时候,自动执行Flyway 更新数据库的操作。
问题1: 当flyway 还在更新数据库,没有完成更新操作之前,应用程序的其他逻辑已经开始使用数据库进行其他操作了,会导致应用程序产生很多bug
解决办法:
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" depends-on="flywayMigration">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" depends-on="flywayMigration">
<property name="dataSource" ref="dataSource" />
</bean>
总结