SpringBoot集成Flyway

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: Flyway:官方解释:Flyway 将 DevOps 扩展到您的数据库,以加速软件交付并确保代码质量。从版本控制到持续交付,Flyway 以应用程序交付流程为基础,实现数据库部署自动化。官方解释总是那么拗口和不说人话,当然通过加粗的关键字我们基本也能够了解到Flyway的功能特性。通俗来说,Flyway可以作为数据库迁移工具服务到我们的应用程序升级发布流程中,减少人为处理sql脚本带来的繁琐和易出错问题。例如,当我们的一个业务微服务从1.5.0升级到1.5.1的时候涉及到数据库的改动(DDL、DML)可以交给Flyway处理,我们无需关心。

[toc]

Flyway 简介

官方解释:Flyway 将 DevOps 扩展到您的数据库,以加速软件交付确保代码质量。从版本控制到持续交付,Flyway 以应用程序交付流程为基础,实现数据库部署自动化

官方解释总是那么拗口和不说人话,当然通过加粗的关键字我们基本也能够了解到Flyway的功能特性。

通俗来说,Flyway可以作为数据库迁移工具服务到我们的应用程序升级发布流程中,减少人为处理sql脚本带来的繁琐和易出错问题。

例如,当我们的一个业务微服务从1.5.0升级到1.5.1的时候涉及到数据库的改动(DDL、DML)可以交给Flyway处理,我们无需关心。

Flyway发展至今,已经只是一个代名词了,有FlywayDesktop,FlywaCLI,FlywayApi等等,老外擅长做生态,总之我们需要明确的是这个东西是服务于数据库迁移的就可以了。

Flyway工作流程

在实际项目开发中是否遇到这样的烦恼:

  • 开发环境没有问题,一升级,线上就出问题,一顿排查到深夜,最终发现是漏掉了一个sql脚本没有执行
  • 运维部署的时候突然问了一句本次升级有需要执行的sql吗?开发一脸懵,由于开发周期长,是否有sql,开发也忘记了
  • 由于开发人员多,每个人都把自己开发的功能涉及到的sql变更单独记录,到了交付测试的时候,sql一汇总,要么是有语法问题,就是执行顺序问题,反正是又得开发再整理一遍,部署预生产和生产同理
  • ......

Flyway就可以很优雅的解决上述问题。

  • 首先,在开发前,引入Flyway到项目中,并提前做好技术调研
  • 然后,在开发阶段,定义好本次迭代的版本号,创建好本次需要迁移的脚本文件名称到 resource 目录下,并昭告所有开发人员,sql统一记录到这个文件中
  • 最后,在开发完毕的时候,sql文件也就整理完毕了,此时只需要打包部署测试环境就好了,当程序在测试环境启动的时候,会自动执行resource目录下的数据库迁移脚本,并且如已经执行,不会重复执行
  • 需要注意的是,引入Flyway就要按照它的要求来,所有sql都需要记录在迁移脚本中,不可偷偷执行sql,不然部署其他环境就炸锅了

入门实践

以SpringBoot为例,SpringBoot官方推荐使用Flyway,引入pom将完成自动配置

pom


<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-mysql</artifactId>
</dependency>


<dependency>
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
    <scope>runtime</scope>
</dependency>
  • 如果使用flyway版本在 8.2.0及之前,可以直接使用flyway-core(groupId=org.flywaydb;artifaceId=flyway-core;version=8.2.0)的依赖
  • flyway在8.2.1版本移除了mysql的默认支持,并创建了一个新的artifactId,即 flyway-mysql

yml


server:
  port: 9009
logging:
  level:
    com.ramble: debug
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.1.32:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: LDr3SvzQPCjxSkf7
  jpa:
    show-sql: true
  flyway:
    baseline-on-migrate: true
    baseline-version: 0
  • baseline-on-migrate:是否自动创建迁移记录表,默认为false,需要设置为true,否则启动报错。flyway的原理就是依靠一个迁移记录表来管理各个版本的迁移脚本执行情况
  • baseline-version:迁移版本初始版本号,默认为1。

迁移sql脚本

在resources目录下创建db文件夹,然后在db文件夹下创建migration文件夹,最后创建V1.0.1__migration.sql的迁移脚本文件。

在V1.0.1__migration.sql 中写入如下sql:


INSERT INTO `user` (`id`, `name`, `state`) VALUES ('123', '漫步科技', 666);
  • classpath:/db/migration 目录为flyway默认的迁移脚本存放目录,可以通过flyway.locations进行配置
  • 迁移脚本文件名称:flyway的实现就是根据判断迁移记录表和迁移脚本文件名称来实现的。对于版本升级需要执行的sql,文件名称必须以“V”开头,后面跟版本号,再跟两个下划线,再跟自定义名称,最后跟“.sql”
  • V1.0.1__migration.sql:sql的内容就是在版本1.0.1中新增了一条数据

启动程序

启动程序之后库里将新增一个表 flyway_schema_history,此表是flyway自动生成的,同时会向user表中新增 一条数据。

启动日志,大概如下:

仅作参考



2023-07-30 16:11:25.072  INFO 16792 --- [           main] o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 8.5.13 by Redgate
2023-07-30 16:11:25.072  INFO 16792 --- [           main] o.f.c.internal.license.VersionPrinter    : See what's new here: https://flywaydb.org/documentation/learnmore/releaseNotes#8.5.13
2023-07-30 16:11:25.072  INFO 16792 --- [           main] o.f.c.internal.license.VersionPrinter    : 
2023-07-30 16:11:25.078  INFO 16792 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2023-07-30 16:11:25.248  INFO 16792 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2023-07-30 16:11:25.278  INFO 16792 --- [           main] o.f.c.i.database.base.BaseDatabaseType   : Database: jdbc:mysql://192.168.1.32:3306/test (MySQL 8.0)
2023-07-30 16:11:25.493  INFO 16792 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 3 migrations (execution time 00:00.080s)
2023-07-30 16:11:25.625  INFO 16792 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema `test`: 1.0.1
2023-07-30 16:11:25.896  INFO 16792 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `test` to version "1.0.2 - migration"
2023-07-30 16:11:26.199  INFO 16792 --- [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 1 migration to schema `test`, now at version v1.0.2 (execution time 00:00.675s)

总结

上述实践演示了在SpringBoot中集成flyway,并做了一个简单的版本升级sql的迁移。

在实际开发中,只要每个迭代开始之前,创建好迁移文件,然后开发人员往里面填写sql。

在填写过程中,也可以看看其他人填写的sql,确保团队中所有人能大概知道别人的sql是否对自己有影响,还能互相检查一下是否有语法问题。

当阶段性开发完毕,直接升级程序就可以顺带迁移数据库了。

如果在操作过程中遇到异常,还可以通过删除flyway_schema_history 表记录或者修改迁移脚本名字来回滚或者重试操作。

本文仅作为入门参考,flyway实际可做的事情还有很多。写的不对的地方,欢迎大家勘误,没有写道的部分,也希望大家评论里讨论。

原理

  • 创建一个迁移记录表 flyway_schema_history
  • 应用启动的时候扫描resources下的特定sql文件
  • 将扫描到的sql文件进行排序
  • 与迁移记录表中的数据进行对比,并执行sql文件

常见问题

Unsupported Database

程序启动报如下错误


Caused by: org.flywaydb.core.api.FlywayException: Unsupported Database: MySQL 8.0

当pom中 引入flyway-core并且版本高于8.2.0将引发此异常。

原因是从8.2.1开始,flyway对mysql的支持拆分出去了,使用flyway-mysql支持。

解决方案有两个:

  • 降低版本到8.2.0
  • 替换依赖为flyway-mysql

No migration necessary

一起配置正常,程序启动不报错,但是脚本就是没有执行,日志中一直提示没有需要迁移的必要(No migration necessary)。

可能的原因:迁移脚本没有放在classpath:db/migration 下,并且也没有配置 flyway.locations

解决办法:创建db文件夹,在db下创建migration文件夹;或者配置 flyway.locations属性

思考

  • 多数据源如何玩?

引用

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
Java Maven Docker
gitlab-ci 集成 k3s 部署spring boot 应用
gitlab-ci 集成 k3s 部署spring boot 应用
|
21天前
|
XML Java 数据库连接
SpringBoot集成Flowable:打造强大的工作流管理系统
在企业级应用开发中,工作流管理是一个核心组件,它能够帮助我们定义、执行和管理业务流程。Flowable是一个开源的工作流和业务流程管理(BPM)平台,它提供了强大的工作流引擎和建模工具。结合SpringBoot,我们可以快速构建一个高效、灵活的工作流管理系统。本文将探讨如何将Flowable集成到SpringBoot应用中,并展示其强大的功能。
71 1
|
1月前
|
JSON Java API
springboot集成ElasticSearch使用completion实现补全功能
springboot集成ElasticSearch使用completion实现补全功能
35 1
|
21天前
|
XML 存储 Java
SpringBoot集成Flowable:构建强大的工作流引擎
在企业级应用开发中,工作流管理是核心功能之一。Flowable是一个开源的工作流引擎,它提供了BPMN 2.0规范的实现,并且与SpringBoot框架完美集成。本文将探讨如何使用SpringBoot和Flowable构建一个强大的工作流引擎,并分享一些实践技巧。
58 0
|
2月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
114 1
|
2月前
|
存储 前端开发 Java
Spring Boot 集成 MinIO 与 KKFile 实现文件预览功能
本文详细介绍如何在Spring Boot项目中集成MinIO对象存储系统与KKFileView文件预览工具,实现文件上传及在线预览功能。首先搭建MinIO服务器,并在Spring Boot中配置MinIO SDK进行文件管理;接着通过KKFileView提供文件预览服务,最终实现文档管理系统的高效文件处理能力。
318 11
|
3月前
|
XML Java 关系型数据库
springboot 集成 mybatis-plus 代码生成器
本文介绍了如何在Spring Boot项目中集成MyBatis-Plus代码生成器,包括导入相关依赖坐标、配置快速代码生成器以及自定义代码生成器模板的步骤和代码示例,旨在提高开发效率,快速生成Entity、Mapper、Mapper XML、Service、Controller等代码。
springboot 集成 mybatis-plus 代码生成器
|
3月前
|
Java Spring
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
本文介绍了如何在Spring Boot项目中集成Swagger 2.x和3.0版本,并提供了解决Swagger在Spring Boot中启动失败问题“Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerEx”的方法,包括配置yml文件和Spring Boot版本的降级。
springboot 集成 swagger 2.x 和 3.0 以及 Failed to start bean ‘documentationPluginsBootstrapper‘问题的解决
|
2月前
|
Java Spring
springboot 学习十一:Spring Boot 优雅的集成 Lombok
这篇文章是关于如何在Spring Boot项目中集成Lombok,以简化JavaBean的编写,避免冗余代码,并提供了相关的配置步骤和常用注解的介绍。
105 0
|
4月前
|
NoSQL 关系型数据库 MySQL
SpringBoot 集成 SpringSecurity + MySQL + JWT 附源码,废话不多直接盘
SpringBoot 集成 SpringSecurity + MySQL + JWT 附源码,废话不多直接盘
157 2