springboot通过钩子实现_SpringBoot实现Flyway的Callback回调钩子

背景

产品迭代使用CI/CD升级过程中,需要对不同发布环境的不同产品版本进行数据库迭代升级,我们在中间某次产品迭代时加入了Flyway中间件以实现数据库结构的自动化升级。

需求

由于是迭代过程中加入的Flyway,而不是一开始就使用,所以Flyway的版本表和版本记录数据在已经发布过的环境中是不存在的,而且每个环境的产品版本也不同,数据库结构迭代升级首先需要确定当前产品的版本,再执行相应的升级脚本。所以我们需要在发布环境升级时,在Flyway执行之前先根据数据库现状写入版本表和版本记录数据,才能让Flyway正常执行迭代升级脚本。

Flyway Hooks/Callback

查阅官方文档知道Flyway有个Hooks,官网文档,文档详细描述如下:

Building upon that are the Java-based Callbacks when you need more power or flexibility in a Callback than SQL can offer you.

They can be created by implementing the Callback interface:

public class MyNotifierCallback implementsCallback {//Ensures that this callback handles both events

@Overridepublic booleansupports(Event event, Context context) {return event.equals(Event.AFTER_MIGRATE) ||event.equals(Event.AFTER_MIGRATE_ERROR);

}//Not relevant if we don‘t interact with the database

@Overridepublic booleancanHandleInTransaction(Event event, Context context) {return true;

}//Send a notification when either event happens.

@Overridepublic voidhandle(Event event, Context context) {

String notification= event.equals(Event.AFTER_MIGRATE) ? "Success" : "Failed";//... Notification logic ...

notificationService.send(notification);

}

String getCallbackName() {return "MyNotifier";

}

}

In order to be picked up by Flyway, Java-based Callbacks must implement the Callback interface. Flyway will automatically scan for and load all callbacks found in the db/callback package. Additional callback classes or scan locations can be specified by the flyway.callbacks configuration property.

SpringBoot实现

根据官方文档描述,需要实现Callback并配置flyway.callbacks参数,但是在springboot配置文件中并没有找到关于spring.flyway.callbacks或者flyway.callbacks的配置项

查看了下源码找到了原因,callbacks属性被定义为了final,所以配置文件中不能设置callbacks配置项,关键代码截图如下:

public class Flyway implementsFlywayConfiguration {private final Listcallbacks;public voidsetCallbacks(FlywayCallback... callbacks) {this.callbacks.clear();this.callbacks.addAll(Arrays.asList(callbacks));

}

}

有个callbacks的set方法,可以尝试用spring注入的方式配置,实现代码如下:

importlombok.SneakyThrows;importlombok.extern.slf4j.Slf4j;importorg.apache.commons.collections.CollectionUtils;importorg.flywaydb.core.api.MigrationInfo;importorg.flywaydb.core.api.callback.FlywayCallback;importorg.springframework.context.annotation.Configuration;import java.sql.*;importjava.util.ArrayList;importjava.util.List;/*** Flyway迭代升级SQL脚本钩子

* 主要作用:

* 1、初始化VERSION表

* 2、写入当前迭代版本号,根据数据库中是否存在数据表判断*/@Slf4j

@Configurationpublic class InitFlywayCallback implementsFlywayCallback {

@Overridepublic voidbeforeClean(Connection connection) {

}

@Overridepublic voidafterClean(Connection connection) {

}

@Overridepublic voidbeforeMigrate(Connection connection) {

}

@Overridepublic voidafterMigrate(Connection connection) {

}

@Overridepublic voidbeforeUndo(Connection connection) {

}

@Overridepublic voidbeforeEachUndo(Connection connection, MigrationInfo migrationInfo) {

}

@Overridepublic voidafterEachUndo(Connection connection, MigrationInfo migrationInfo) {

}

@Overridepublic voidafterUndo(Connection connection) {

}

@Overridepublic voidbeforeEachMigrate(Connection connection, MigrationInfo migrationInfo) {

}

@Overridepublic voidafterEachMigrate(Connection connection, MigrationInfo migrationInfo) {

}

@SneakyThrows

@Overridepublic voidbeforeValidate(Connection connection) {

log.info("Flyway执行拦截");}

@Overridepublic voidafterValidate(Connection connection) {

}

@Overridepublic voidbeforeBaseline(Connection connection) {

}

@Overridepublic voidafterBaseline(Connection connection) {

}

@Overridepublic voidbeforeRepair(Connection connection) {

}

@Overridepublic voidafterRepair(Connection connection) {

}

@Overridepublic voidbeforeInfo(Connection connection) {

}

@Overridepublic voidafterInfo(Connection connection) {

}

}

项目启动打印结果如下:

2020-12-23 09:42:53.025 dassets 13092 [--] [ INFO] [org.flywaydb.core.internal.util.VersionPrinter.info:44] [ main] [Flyway Community Edition 5.0.7by Boxfuse]2020-12-23 09:43:03.461 dassets 13092 [--] [ INFO] [org.flywaydb.core.internal.database.DatabaseFactory.info:44] [ main] [Database: jdbc:mysql://10.101.6.105:3306/user (MySQL 5.7)]

2020-12-23 09:43:03.675 dassets 13092 [--] [ INFO] [com.cestc.dassets.interceptor.InitFlywayCallback.beforeValidate:76] [ main] [Flyway执行拦截]

至此,callback执行成功!

最后附一个Flyway的Callback事件描述,官网文档:

NameExecution

beforeMigrate

Before Migrate runs

beforeRepeatables

Before all repeatable migrations during Migrate

beforeEachMigrate

Before every single migration during Migrate

beforeEachMigrateStatement Flyway Teams

Before every single statement of a migration during Migrate

afterEachMigrateStatement Flyway Teams

After every single successful statement of a migration during Migrate

afterEachMigrateStatementError Flyway Teams

After every single failed statement of a migration during Migrate

afterEachMigrate

After every single successful migration during Migrate

afterEachMigrateError

After every single failed migration during Migrate

afterMigrate

After successful Migrate runs

afterVersioned

After all versioned migrations during Migrate

afterMigrateError

After failed Migrate runs

Before Undo runs

beforeEachUndo Flyway Teams

Before every single migration during Undo

beforeEachUndoStatement Flyway Teams

Before every single statement of a migration during Undo

afterEachUndoStatement Flyway Teams

After every single successful statement of a migration during Undo

afterEachUndoStatementError Flyway Teams

After every single failed statement of a migration during Undo

afterEachUndo Flyway Teams

After every single successful migration during Undo

afterEachUndoError Flyway Teams

After every single failed migration during Undo

After successful Undo runs

afterUndoError Flyway Teams

After failed Undo runs

beforeClean

Before Clean runs

afterClean

After successful Clean runs

afterCleanError

After failed Clean runs

beforeInfo

Before Info runs

afterInfo

After successful Info runs

afterInfoError

After failed Info runs

beforeValidate

Before Validate runs

afterValidate

After successful Validate runs

afterValidateError

After failed Validate runs

beforeBaseline

Before Baseline runs

afterBaseline

After successful Baseline runs

afterBaselineError

After failed Baseline runs

beforeRepair

Before Repair runs

afterRepair

After successful Repair runs

afterRepairError

After failed Repair runs

原文:https://www.cnblogs.com/changxy-codest/p/14176849.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用SpringBoot开发应用程序时,数据库迁移是非常重要的一环,这可以使你在开发过程中轻松地更新你的数据库架构,而不会丢失任何数据。Flyway是一个非常流行的数据库迁移工具,它可以让你在应用程序启动时自动执行数据库迁移。 以下是如何在SpringBoot中使用Flyway的步骤: 1. 添加Flyway依赖 在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency> ``` 2. 配置Flyway 在application.properties文件中添加以下配置: ``` # 数据库连接配置 spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=root spring.datasource.password=123456 # Flyway配置 spring.flyway.baseline-on-migrate=true # 第一次执行时,自动从版本1开始执行 spring.flyway.locations=classpath:db/migration # 数据库迁移脚本位置 ``` 3. 创建数据库迁移脚本 在src/main/resources/db/migration目录下创建数据库迁移脚本,文件名必须遵循以下规则: ``` V1__initial.sql V2__add_new_table.sql V3__update_existing_table.sql ``` 其中,V1、V2、V3是版本号,__后面是描述性的名称,.sql是文件扩展名。 4. 启动应用程序 当你启动应用程序时,Flyway将自动执行所有未执行的数据库迁移脚本。 总结: 通过使用Flyway,你可以轻松地管理你的数据库迁移,并确保在应用程序启动时自动执行它们。这为你的应用程序提供了极大的灵活性,并使你能够快速地更新数据库架构,而不会丢失任何数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值