当前位置:   article > 正文

多数据源 使用 flyWay 进行数据库管理_flyway mysql

flyway mysql

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


多数据源 使用 flyWay 进行数据库管理

flyway是一个开源的数据库迁移工具,它能够自动管理SQL脚本的执行,从而使数据库版本控制和升级变得更加容易。它支持各种数据库(Oracle,MySQL,PostgreSQL,SQL Server等)和多种脚本语言(SQL,Java,Groovy等)。用户可以使用命令行或API将SQL脚本打包在项目中,然后在开发过程中对数据库进行管理和升级。flyway对于Web开发人员来说是非常有用的,它可以自动检测和执行需要执行的脚本。

1. 环境

mysql : 5.7
springBoot 版本: 2.7.3

2. flyway版本 与 MySQL 版本 对应关系
  • Flyway 6.x.x:支持MySQL 5.5及以上版本;
  • Flyway 7.x.x:支持MySQL 5.6及以上版本;
  • Flyway 8.x.x:支持MySQL 5.7及以上版本;
  • Flyway 8.2.x:支持MySQL 8.0及以上版本。

需要注意的是,Flyway对于不同版本的MySQL数据库,支持的功能也会有所不同。因此,在选择使用哪个版本的Flyway时,需要根据实际情况来进行选择。

3. flyway 脚本文件命名方式
序号类型内容格式备注
1版本迁移以V开头,只会执行一次V{版本号(可以用点或下划线)}{分隔符(默认:__)}{描述}.sql
2回退迁移以U开头U{版本号(可以用点或下划线)}{分隔符(默认:__)}{描述}.sql执行一旦发生破坏性更改,会很麻烦,项目中一般不用。
3可重复执行迁移以R开头R{分隔符(默认:__)}{描述}.sql

优先级:
V开头的SQL执行优先级要比R开头的SQL 优先级高。

注意:
对于V开头的SQL脚本,版本号需要唯一,否则Flyway执行会报错;R开头的SQL脚本,如有变化可以执行多次。

4. flyway工作流程
  1. 项目启动、数据库连接池建立、flyway 运行;
  2. 初次使用时,如果不设置table值,flyway会默认创建一个 flyway_schema_history 表,用于记录sql执行记录;
  3. 如果不配做扫描路径,Flyway会扫描项目 classpath:db/migration 下的所有sql脚本,与存储记录sql执行表里的记录做对比,当validate-on-migrate为true时,进行校验,比如对于V开头的SQL脚本,版本号需要唯一,否则Flyway执行会报错等等…,一旦发现问题,Flyway抛出异常并停止项目;
  4. 校验通过,则根据表中的sql记录最大版本号,忽略所有版本号不大于该版本的脚本。再按照版本号从小到大,逐个执行其余脚本。
5. 知识点补充
  1. flyway执行migrate必须在空白的数据库上进行,否则报错;
  2. 对于已经有数据的数据库,必须先baseline,然后才能migrate;
  3. clean操作是删除数据库的所有内容,包括baseline之前的内容;
  4. 尽量不要修改已经执行过的SQL,即便是R开头的可反复执行的SQL,它们会不利于数据迁移;
  5. 当需要做数据迁移的时候,更换一个新的空白数据库,执行下migrate命令,所有的数据库更改都可以一步到位地迁移过去;
6. 集成的时候常见错误
6.1. user_variables_by_thread没有访问权限

Caused by: java.sql.SQLSyntaxErrorException: SELECT command denied to user ‘TESTTWO’@‘localhost’ for table ‘user_variables_by_thread’

在这里插入图片描述
解决:

GRANT SELECT ON performance_schema.user_variables_by_thread TO 'TESTTWO'@'localhost';
GRANT SELECT ON performance_schema.user_variables_by_thread TO 'TESTONE'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;
  • 1
  • 2
  • 3
  • 4
6.2. MySQL不支持Flyway社区版,只支持Flyway企业版

.FlywayEditionUpgradeRequiredException: Flyway Teams Edition or MySQL upgrade required: MySQL 5.7 is no longer supported by Flyway Community Edition, but still supported by Flyway Teams Edition.
在这里插入图片描述
大致意思是:MySQL 5.7不支持Flyway社区版,只支持Flyway企业版,提出的解决方案是改成企业版或升级MySQL。

解决:
降低Flyway版本性价比应该是最高的,最快速的。

6.3. SQL注入违规

sql injection violation, comment not allow :
在这里插入图片描述
因为我这里用的多数据源有filter,把防注入去掉就好
解决:
把这里的wall 去掉。
在这里插入图片描述

7. Flyway 集成 SpringBoot 实战
7.1. 依赖
        <!--多数据源-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.22</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
                <!-- flyway -->
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
            <version>5.2.3</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
7.2. 配置
package org.example.config;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flywaydb.core.Flyway;
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 org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.io.File;
import java.util.Map;

/**
 * @author yangzhenyu
 * @version 1.0
 * @description:
 * @date 2023/5/5 13:36
 */
@Slf4j
@Configuration
@RequiredArgsConstructor
@EnableTransactionManagement
public class FlywayConfig {
    private final DataSource dataSource;

    // 是否启用 Flyway,true 启用,false 不启用
    @Value("${spring.flyway.enabled: false}")
    private Boolean FLYWAY_ENABLED;
    // 指定 SQL 脚本文件夹路径 这里写主库路径,然后在配置类中转换
    @Value("${spring.flyway.locations: classpath:db/master}")
    private String SQL_LOCATION;
    // 版本更新历史记录表
    @Value("${spring.flyway.table: yzy_db_version}")
    private String VERSION_TABLE;


    // 是否可以无序执行
    @Value("${spring.flyway.out-of-order: false}")
    private Boolean OUT_OF_ORDER;

    // 迁移前校验 SQL 文件是否存在问题
    @Value("${spring.flyway.validate-on-migrate: true}")
    private Boolean VALIDATE_ON_MIGRATE;

    // 编码格式,默认UTF-8
    @Value("${spring.flyway.encoding: UTF-8}")
    private String ENCODING;
    // 迁移sql脚本文件名称的前缀,默认V
    @Value("${spring.flyway.sql-migration-prefix: V}")
    private String SQL_MIGRATION_PREFIX;

    //迁移sql脚本文件名称的分隔符,默认2个下划线__
    @Value("${spring.flyway.sql-migration-separator: __}")
    private String SQL_MIGRATION_SEPARATOR ;

    // 迁移sql脚本文件名称的后缀
    @Value("${spring.flyway.sql-migration-suffixes: .sql}")
    private String SQL_MIGRATION_SUFFIXES ;

    // 非空数据库初始化Flyway时需要打开此开关进行Baseline操作 (如果数据库不是空表,需要设置成 true,否则启动报错)
    @Value("${spring.flyway.baseline-on-migrate: true}")
    private Boolean BASELINE_ON_MIGRATE;

    // 基础版本号  与 baseline-on-migrate: true 搭配使用
    @Value("${spring.flyway.baseline-version: 1}")
    private String BASELINE_VERSION;

    @Primary
    @Bean
    @PostConstruct
    public void migrateOrder() {

        if (FLYWAY_ENABLED) {
            log.info("调用数据库生成工具");
            SQL_LOCATION = SQL_LOCATION.split("/")[0]; // 多数据源的配置
            DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
            Map<String, DataSource> dataSources = ds.getDataSources();
            dataSources.forEach((k, v) -> {
                log.info("正在执行多数据源生成数据库文件 " + k);
                Flyway flyway = Flyway.configure()
                        .dataSource(v)
                        .locations(SQL_LOCATION + File.separator + k)
                        .baselineOnMigrate(BASELINE_ON_MIGRATE)
                        .table(VERSION_TABLE)
                        .outOfOrder(OUT_OF_ORDER)
                        .validateOnMigrate(VALIDATE_ON_MIGRATE)
                        .encoding(ENCODING)
                        .sqlMigrationPrefix(SQL_MIGRATION_PREFIX)
                        .sqlMigrationSeparator(SQL_MIGRATION_SEPARATOR)
                        .sqlMigrationSuffixes(SQL_MIGRATION_SUFFIXES)
                        .baselineVersion(BASELINE_VERSION)
                        .load();
                flyway.migrate();
            });
        }
    }
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
spring:
  datasource:
    dynamic: # druid连接池配置
      primary: master #默认数据源
      datasource:
        master: #主库配置
          username: TESTONE
          password: TESTONE
          driver-class-name: ${datasource_driver_class_name:com.mysql.cj.jdbc.Driver}
          url: ${datasource_url:jdbc:mysql://localhost:3306/TESTONEDB?characterEncoding=UTF-8&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true}
          druid:
            initial-size: 5 #启动程序时,在连接池中初始化多少个连接
            max-active: 20 #连接池中最多支持多少个活动会话
            min-idle: 5 #回收空闲连接时,将保证至少有minIdle个连接
            max-wait: 60000 #程序向连接池中请求连接时,超过maxWait的值后,认为本次请求失败,即连接池
            filters: stat,slf4j
        slave: #从库配置
          username: TESTTWO
          password: TESTTWO
          driver-class-name: ${datasource_driver_class_name:com.mysql.cj.jdbc.Driver}
          url: ${datasource_url:jdbc:mysql://localhost:3306/TESTTWODB?characterEncoding=UTF-8&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true}
          druid:
            initial-size: 5 #启动程序时,在连接池中初始化多少个连接
            max-active: 20 #连接池中最多支持多少个活动会话
            min-idle: 5 #回收空闲连接时,将保证至少有minIdle个连接
            max-wait: 60000 #程序向连接池中请求连接时,超过maxWait的值后,认为本次请求失败,即连接池
            filters: stat,slf4j
  flyway:
    enabled: true # 是否启用 Flyway,true 启用,false 不启用
    # 版本更新历史记录表
    table: yzy_db_version
    # 非空数据库初始化Flyway时需要打开此开关进行Baseline操作
    baseline-on-migrate: true
    # 是否可以无序执行
    out-of-order: false
    # 迁移前校验 SQL 文件是否存在问题
    validate-on-migrate: false
    locations: classpath:db/master  # 指定 SQL 脚本文件夹路径 这里写主库路径,然后在配置类中转换
    # 编码格式,默认UTF-8
    encoding: UTF-8
    # 迁移sql脚本文件名称的前缀,默认V
    sql-migration-prefix: V
    # 迁移sql脚本文件名称的分隔符,默认2个下划线__
    sql-migration-separator: __
    # 迁移sql脚本文件名称的后缀
    sql-migration-suffixes: .sql
    # 基础版本号
    baseline-version: 1

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
7.3. Flyway 测试脚本

在这里插入图片描述
V20230505_1__yzy_db_version_remark.sql


alter table yzy_db_version comment 'flyway数据库版本控制表';

  • 1
  • 2
  • 3

V20230505_2__新增测试表.sql

create table flyway_test
(
    ID   int(18) auto_increment comment 'id'
        primary key,
    AGE  int(100)     not null comment '年龄',
    NAME varchar(100) null comment '姓名',
    CREATE_TIME    datetime null comment '删除时间'

)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
7.4. 测试

项目启动,查看数据库信息:
select * from yzy_db_version;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
说明集成成功!!!

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/595621
推荐阅读
相关标签
  

闽ICP备14008679号