使用 Flyway 管理开发和测试环境的 Sql Migration

598 阅读2分钟

新建 Spring Boot 项目

  1. 打开页面 start.spring.io/
  2. 添加依赖 Flyway MigrationMySQL DriverJDBC API
  3. 下载

添加 Flyway plugin

  1. 解压并打开上一步下载的文件
  2. 在 pom.xml 文件的 plugins 标签下添加 maven plugin
<plugin>
   <groupId>org.flywaydb</groupId>
   <artifactId>flyway-maven-plugin</artifactId>
   <version>8.0.1</version>
   <configuration>
      <configFiles>
         <configFile>config/flyway.conf</configFile>
      </configFiles>
   </configuration>
</plugin>

准备开发环境数据库

CREATE DATABASE flywaydb;
CREATE USER 'dev'@'localhost' IDENTIFIED BY 'password'; -- 创建用户
GRANT ALL ON flywaydb.* TO 'dev'@'localhost'; -- 给用户授权

Spring Boot 开发环境配置

  1. 修改文件 src/main/resources/application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/flywaydb
spring.datasource.username=dev
spring.datasource.password=password

spring.flyway.enabled=false # 只使用 Flyway 管理开发和测试环境的 sql migration,所以在 Spring Boot 中禁用 Flyway

Flyway 开发环境配置文件

  1. 项目根目录下新建文件 config/flyway.conf,文件路径和 maven plugin 中 configFile 一致
  2. 文件内容为:
flyway.url=jdbc:mysql://localhost:3306/flywaydb
flyway.user=dev
flyway.password=password

Migration 文件

  1. 新建文件 src/main/resources/db/migration/V1__Create_users_table.sql
  2. 文件内容为:
CREATE TABLE `users`
(
    id   int         NOT NULL,
    name varchar(50) NOT NULL,
    PRIMARY KEY (id)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_unicode_ci;

运行 Flyway Migrate

  1. 项目根目录运行 mvn flyway:clean flyway:migrate
  2. 运行后查看数据库,如下图:

截图_选择区域_20220618122853.png

开发环境添加 seeds 数据

  1. 新建文件 src/main/java/db/seeds/V100__Add_seeds.java,文件内容
package db.seeds;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.flywaydb.core.internal.jdbc.JdbcTemplate;

public class V100__Add_seeds extends BaseJavaMigration {

    @Override
    public void migrate(Context context) throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(context.getConnection());
        jdbcTemplate.execute("INSERT INTO users (id, name) VALUES (1, 'user name')");
    }
}
  1. config/flyway.conf文件添加一行配置
flyway.locations=classpath:db/migration,classpath:db/seeds
  1. 项目根目录下运行
mvn clean compile flyway:clean flyway:migrate
# clean 和 compile 命令不可少,因为 flyway.locations 配置的是 classpath,
# 每次 flyway:migrate 前执行 compile 保证 classpath 目录下的文件是最新的。
  1. 查看数据库,发现文件src/main/java/db/seeds/V100__Add_seeds.java中的 sql 已被执行

截图_选择区域_20220618134053.png

准备测试环境数据库

CREATE DATABASE flywaydb_test;
CREATE USER 'test'@'localhost' IDENTIFIED BY 'password'; -- 创建用户
GRANT ALL ON flywaydb_test.* TO 'test'@'localhost'; -- 给用户授权

Flyway 开发环境配置文件

  1. 项目根目录下新建文件 config/flyway-test.conf
  2. 文件内容为:
flyway.url=jdbc:mysql://localhost:3306/flywaydb_test
flyway.user=test
flyway.password=password
  1. 执行命令
mvn clean compile flyway:clean flyway:migrate -Dflyway.configFiles=config/flyway-test.conf
# 因为 flyway plugin 中的 configFile 配置的是 `config/flyway.conf`
# 所以测试环境通过参数 `-Dflyway.configFiles` 来替换 flyway 配置文件
  1. 查看数据库 flywaydb_test,如下图,可以看到只执行了 src/main/resources/db/migration 目录下的文件,并没有执行 src/main/java/db/seeds下的文件,这也正是测试环境想要的,保持一个干净的测试库

截图_选择区域_20220618140103.png

Spring Boot 测试环境配置

  1. 新建文件 src/test/resources/application-test.properties,文件内容
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/flywaydb_test
spring.datasource.username=test
spring.datasource.password=password
  1. 修改文件 src/test/java/com/example/demo/DemoApplicationTests.java,给类 DemoApplicationTests 添加注解
@Transactional
@TestPropertySource({"classpath:application-test.properties"})
  1. 在类 DemoApplicationTests 中添加测试方法
@Test
void testDemo() {
    jdbcTemplate.execute("INSERT INTO users (id, name) VALUES (1, 'test user name')");
    jdbcTemplate.query("SELECT * FROM users WHERE id = 1", (rs, rowNum) -> {
        assert rs.getInt(1) == 1;
        assert rs.getString(2).equals("test user name");
        return null;
    });
}
  1. 执行命令
mvn clean compile flyway:clean flyway:migrate -Dflyway.configFiles=config/flyway-test.conf test

可以看到测试通过

截图_选择区域_20220618142703.png

简化 Maven 命令

  1. 根目录下新建文件 reset.sh,文件内容
#!/bin/bash

mvn clean compile flyway:clean flyway:migrate
  1. 根目录下新建文件 test.sh,文件内容
#!/bin/bash

mvn clean compile flyway:clean flyway:migrate -Dflyway.configFiles=config/flyway-test.conf test

Git 仓库

gitee.com/zhangjiashu…