前言

目前很多公司都是通过人工去保护、同步数据库脚本,但经常会遇到疏忽而遗失的状况,一起也是非常吃力耗时

比如说咱们在开发环境对某个表新增了一个字段,而提交测验时却忘了提交该 SQL 脚本,导致呈现 bug 而测验中断,然后影响开发、测验的作业效率

咱们能够运用 Git/ SVN 等东西进行代码的版别操控,一起,数据库也有对应的版别操控东西,能够记载数据库的改变记载

Flyway 是一款开源的数据库版别办理东西,它更倾向于规约优于装备的方法。Flyway 能够独立于使用完成办理并盯梢数据库改变,支撑数据库版别主动晋级,并且有一套默许的规约,不需要复杂的装备,Migrations 能够写成 SQL 脚本,也能够写在 Java 代码中,不仅支撑 Command Line 和 Java API,还支撑 Build 构建东西和 Spring Boot 等,一起在分布式环境下能够安全可靠地晋级数据库,一起也支撑失利康复等

官网主页:Homepage – Flyway (flywaydb.org)

特性

普通 SQL:纯 SQL 脚本(包含占位符替换)没有专有的 XML 格局,没有锁定

无限制:运用 Java 代码来进行一些高级数据操作

零依赖:只需运行在 Java6(及以上)和数据库所需的 JDBC 驱动

约好优于装备:搬迁时,主动查找系统文件和类途径中的 SQL 文件或 Java 类

高可靠性:在集群环境下进行数据库晋级是安全可靠的

云支撑:完全支撑 Microsoft SQL Azure, Google Cloud SQL & App Engine、Heroku Postgres 和 Amazon RDS

主动搬迁:运用 Flyway 提供的 API,让使用发动和搬迁一起作业

快速失利:损坏的数据库或失利的搬迁能够防止使用程序发动

数据库清理:在一个数据库中删去所有的表、视图、触发器,而不是删去数据库本身

原理

当 Flyway 连接数据库中的 schema 后,会先查看是否已存在 flyway_schema_history 表,假如没有则创立。该表用于盯梢数据库的状况,如数据搬迁的版别,搬迁成功状况等信息

flyway_schema_history 存在后,Flyway 会扫描文件系统或使用中的 classpath 目录的数据搬迁文件,然后依据它们的版别号进行按序搬迁,如下图:

Flyway 数据库版别办理 | 专业解决方案

由于 flyway_schema_history 表中记载了搬迁的版别号,假如文件的版别号小于或等于标记为当时版别的版别号,则忽略它们不履行

实战

数据库:MySQL 8.0

官方文档:Quickstart – API – Flyway – Product Documentation (red-gate.com)

Maven

首要新建 Maven 项目

Flyway 数据库版别办理 | 专业解决方案

增加依赖

        <!-- flyway -->
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
            <version>5.2.4</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.15</version>
        </dependency>

创立搬迁

首要咱们需要创立搬迁文件 src/main/resources/db/migration

然后装备数据库搬迁文件,实施第一次搬迁 src/main/resources/db/migration/V1__Create_person_table.sql

留意:V1 后边是两个下划线,有必要是这样的格局

create table PERSON
(
    ID   int          not null,
    NAME varchar(100) not null
);

然后装备主发动函数

public class App {
    public static void main(String[] args) {
        String url = "jdbc:mysql://127.0.0.1:3306/flyway?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false&serverTimezone=GMT+8";
        String user = "root";
        String password = "111111";
        Flyway flyway = Flyway.configure().dataSource(url, user, password).load();
        // 创立 flyway_schema_history 表
//		flyway.baseline();
        // 删去 flyway_schema_history 表中失利的记载
//		flyway.repair();
        // 查看 sql 文件
//		flyway.validate();
        // 履行数据搬迁
        flyway.migrate();
        // 删去当时 schema 下所有表
//		flyway.clean();
    }
}

履行程序

履行 App 程序

注:咱们需要提前创立空数据库 flyway,假如 flyway 不是项目初期引入,后边会给出解决方案

Flyway 数据库版别办理 | 专业解决方案

然后咱们能够看到现在现已创立了 flyway_schema_history 表和 PERSON 表,数据现已成功搬迁到指定数据库中

Flyway 数据库版别办理 | 专业解决方案

现在假如系统晋级,需要做数据搬迁时,咱们只需在 db/migration 目录下再放置新版别的 sql 文件即可

现在咱们装备第2次搬迁,创立文件 src/main/resources/db/migration/V2__Add_people.sql

insert into PERSON (ID, NAME)
values (1, 'Axel');
insert into PERSON (ID, NAME)
values (2, 'Mr. Foo');
insert into PERSON (ID, NAME)
values (3, 'Ms. Bar');

然后履行 App ,就能够看到如下履行成功

Flyway 数据库版别办理 | 专业解决方案

SpringBoot

下面整合 flyway 到 springboot

增加依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>

装备 application.yml

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/flyway?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false&serverTimezone=GMT+8
    username: root
    password: 111111
  flyway:
    enabled: true
    # 制止清理数据库表
    clean-disabled: true
    # 假如数据库不是空表,需要设置成 true,不然发动报错
    baseline-on-migrate: true
    # 与 baseline-on-migrate: true 调配运用
    baseline-version: 0
    # 不装备默许为 db/migration 目录
    locations:
      - classpath:db/migration/mysql

假如 flyway 不是项目初期引入,而是在数据库已有表的状况下引入时有必要设置 baseline-on-migrate: true(此刻没有装备 baseline-version: 0),设置该装备发动项目后,flyway 就会在数据库中创立 flyway_schema_history 表,并且会往该表中刺进一条 version = 1 的建表记载,假如搬迁数据有 V1__ 最初的文件,扫描文件会忽略该文件不履行搬迁,从而可能引发其他搬迁数据出错的问题

由于没有履行 V1__ 最初的文件,那么库中就不创立 PERSON 表,在搬迁 V2 刺进数据时就会刺进失利

所以呈现如上问题后,咱们能够先删去flyway_schema_history 表,然后装备文件中设置 baseline-version: 0 即可,或者说修改数据搬迁文件名称也是可行的

其他问题

版别问题

SpringBoot 2.4.4 集成 flyway 版别 7.1.1 (Oracle12.1.0.2 标准版能够履行,企业版不可)

SpringBoot 2.6.0 集成 flyway 版别 8.0.4 (Oracle12.1.0.2 都能够履行)

SQL 脚本命名规范

Prefix Version Separator Description Suffix

Prefix 前缀:V 代表版别搬迁,U 代表撤销搬迁,R 代表可重复搬迁

Version 版别号:版别号通常 . 和整数组成

Separator 分隔符:固定由两个下划线 __ 组成

Description 描绘:由下划线分隔的单词组成,用于描绘本次搬迁的目的

Suffix 后缀:假如是 SQL 文件那么固定由 .sql 组成,假如是根据 Java 类则默许不需要后缀

参考链接

本文由博客一文多发渠道 OpenWrite 发布!