flyway的简单使用

flyway的简单使用

flyway简述

Flyway是一个开源的数据库迁移工具。与配置相比,Flyway极力主张简单和约定。它仅基于7个基本命令: 迁移, 清理, 信息, 验证, 撤消, 基线和 修复。

迁移可以用SQL (支持特定于数据库的语法(例如PL / SQL,T-SQL等)或Java (适用于高级数据转换或处理LOB)的方式编写。

支持的数据库包括 Oracle, SQL Server(包括Amazon RDS和Azure SQL数据库), DB2, MySQL(包括Amazon RDS,Azure数据库和Google Cloud SQL), Aurora MySQL, MariaDB, Percona XtraDB群集, PostgreSQL(包括Amazon RDS,Azure数据库) ,Google Cloud SQL和Heroku), Aurora PostgreSQL, Redshift, CockroachDB, SAP HANA, Sybase ASE, Informix, H2, HSQLDB, Derby, Snowflake, SQLite和 Firebird。

flyway实际使用

spring boot 2.x 集成flyway

搭建环境
  • spring boot-2.2.2.RELEASE
  • mysql 5.7
maven配置
<dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starterartifactId>
        dependency>
        <dependency>
            <groupId>org.flywaydbgroupId>
            <artifactId>flyway-coreartifactId>
            <version>5.2.1version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-jdbcartifactId>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.13version>
        dependency>

        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druid-spring-boot-starterartifactId>
            <version>1.1.16version>
        dependency>
       
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
            <plugin>
                <groupId>org.flywaydbgroupId>
                <artifactId>flyway-maven-pluginartifactId>
                <version>5.0.3version>
            plugin>
        plugins>
    build>
yml配置
# application.yml
server:
  port: 8088

spring:
  profiles:
    active: dev
# application-dev.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/testdb?serverTimezone=GMT%2B8
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    flyway:
      baseline-on-migrate: true
      # locations: classpath:db/migration # 迁移脚本的路径
      enabled: true # 是否开启flyway
      validationQuery: SELECT 1
    type: com.alibaba.druid.pool.DruidDataSource

flyway迁移脚本(.sql文件)默认放在classpath: db/migration文件夹中

flyway的简单使用_第1张图片

启动项目flyway创建版本管理表flyway_schema_history,并遍历db.migraion目录下数据库sql文件。

flyway的简单使用_第2张图片

注意

flyway在执行脚本时,会在源数据表中检查checksum值,并确定上次运行运行到哪一个脚本文件,本次执行时从下一条脚本文件开始执行。

所以需要注意下:

编写脚本的时候不要去修改原有的脚本内容

新的脚本版本号要连续,如果需要重复修改执行脚本可以使用repeatable migration(可重复迁移),编写的sql语句为可重复升级语句。

这里建议多人开发时,先使用repeatable migration模式对一个脚本进行开发,当应用程序发版的时候在定一个Versioned Migrations模式的版本。

Flyway工作模式

文件名格式规定

  • 版本控制:V+版本号+__+描述+.sql
  • 可重复调用:R+__+描述+.sql

具体要求:

  • 版本号和版本描述之间,使用两个下划线分隔。
  • 版本描述之间,使用一个下划线分隔单词。
  • 版本号唯一:不允许多个脚本文件有相同的版本号。

使用Flyway升级,flyway会自动创建一张历史记录表:flyway_schema_history。

flyway遇到的问题

1、时区问题

java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
解决方案

在数据库连接地址后边加上时区,例如

url: jdbc:mysql://localhost:3306/testdb?serverTimezone=GMT%2B8

2、首次创建库问题

程序第一次运行时,并没有手动创建数据库(schema),但是flyway的操作是在已存在的数据库中进行,否则会报错。

解决方案

可以使用druid配合创建。

package com.felton.springbootflyway.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

@Configuration
@Primary //在同样的DataSource中,首先使用被标注的DataSource
public class DataSourceConfig {
//    private Logger log = LoggerFactory.getLogger(DataSourceConfig.class);

    @Value("${spring.datasource.url}")
    //jdbc:mysql://127.0.0.1:3306/insight?useUnicode=true&characterEncoding=utf8&failOverReadOnly=false&allowMultiQueries=true
    private String datasourceUrl;
    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;

    @Bean     //声明其为Bean实例
    public DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();

        datasource.setUrl(datasourceUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);

        try {
            Class.forName(driverClassName);

            String url01 = datasourceUrl.substring(0, datasourceUrl.indexOf("?"));

            String url02 = url01.substring(0, url01.lastIndexOf("/"))+"?serverTimezone=GMT%2B8";

            String datasourceName = url01.substring(url01.lastIndexOf("/") + 1);
            // 连接已经存在的数据库,如:mysql
            Connection connection = DriverManager.getConnection(url02, username, password);
            Statement statement = connection.createStatement();

            // 创建数据库
            statement.executeUpdate("create database if not exists `" + datasourceName + "` default character set utf8 COLLATE utf8_general_ci");

            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }


        return datasource;
    }
}

你可能感兴趣的:(flyway的简单使用)