4

SpringBoot数据库管理 - 用flyway对数据库管理和迁移 - pdai

 1 year ago
source link: https://www.cnblogs.com/pengdai/p/16496471.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

SpringBoot数据库管理 - 用flyway对数据库管理和迁移

作者:@pdai
本文为作者原创,转载请注明出处:https://www.cnblogs.com/pengdai/p/16496471.html




上文介绍了Liquibase,以及和SpringBoot的集成。除了Liquibase之外,还有一个组件Flyway也是经常被使用到的类似的数据库版本管理中间件。本文主要介绍Flyway, 以及SpringBoot集成Flyway。@pdai

需要了解Flyway和要解决的问题,以及一些基础概念,比如变迁(migrations),常用命令(commands)等。

什么是Flyway? 要解决什么问题?

Flyway是一款数据库迁移(migration)工具。简单点说,就是在你部署应用的时候,帮你执行数据库脚本的工具。Flyway支持SQL和Java两种类型的脚本,你可以将脚本打包到应用程序中,在应用程序启动时,由Flyway来管理这些脚本的执行,这些脚本被Flyway称之为migration。

PS: 本质上和liquibase机制一致

按照verion的顺序(和数据库中的更新记录对比,找到未更新的),更新如下

springboot-flyway-11.png

更新记录如下

springboot-flyway-12.png

Flyway中的变迁(migrations)

对于Flyway,对数据库的所有更改都称为变迁(migrations),等同于liquibase中的changeset。

在Flyway中变迁(migrations)定义的更细,包含如下三种:

  1. 版本变迁(Versioned Migrations): 每个版本执行一次,包含有版本、描述和校验和;常用于创建,修改,删除表;插入,修改数据等
  2. 撤销变迁(Undo Migrations): 版本变迁(Versioned Migrations)的反操作。
  3. 可重复变迁(Repeatable Migrations): 可以执行多次,包含描述和校验和(没有版本);主要用于视图,存储过程,函数等

这三种类型对应的格式如下:

springboot-flyway-1.png
  1. 前缀: V 代表版本变迁(Versioned Migrations), U 代表撤销变迁(Undo Migrations), R 代表可重复变迁(Repeatable Migrations)
  2. 版本号: 唯一的版本号,比如V1.0.1
  3. 分隔符: __ (两个下划线)
  4. 描述信息: 描述信息
  5. 后缀: .sql

(PS:撤销变迁(Undo Migrations)在收费版本中)

Flyway中常用命令

Flyway中的常用commands有哪些?什么含义?

Migrate: 是Flyway工作流的核心。它将扫描文件系统或类路径以查找可用的Migrate。它将把它们与已应用于数据库的Migrate进行比较。如果发现任何差异则迁移数据。

springboot-flyway-2.png

Clean: 清除掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作在dev 和 test阶段很好用;(PS:不能用在product环境)

springboot-flyway-3.png

Info: 用于打印所有的Migrations的详细和状态信息,也是通过MetaData和Migrations完成的,可以快速定位当前的数据库版本;

springboot-flyway-4.png

Validate: 验证以及apply的Migrations是否有变更,默认开启的;原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。

springboot-flyway-5.png

Undo: Migrate的反操作, 即回滚操作,这是收费功能

springboot-flyway-6.png

BaseLine:对已经存在数据库Schema结构的数据库一种解决方案。实现在非空数据库新建MetaData表,并把Migrations应用到该数据库;也可以应用到已有表结构的数据库中也可以实现添加Metadata表。

springboot-flyway-7.png

Repair:repair操作能够修复metaData表,该操作在metadata出现错误时很有用

springboot-flyway-9.png

这里主要介绍基于SpringBoot集成flyway来管理数据库的变更。

POM依赖

Maven 包的依赖,主要包含mysql驱动, JDBC(这里spring-boot-starter-data-jpa包含了jdbc包,当然直接引入jdbc包也行),以及flyway包。

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.28</version>
</dependency>
<dependency>
    <groupId>com.github.wenhao</groupId>
    <artifactId>jpa-spec</artifactId>
    <version>3.1.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

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

yml配置

SpringBoot AutoConfig默认已经包含了对flyway的配置,在spring.flyway配置下

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test_db_flyway?useSSL=false&autoReconnect=true&characterEncoding=utf8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: bfXa4Pt2lUUScy8jakXf
  flyway:
    enabled: true
    encoding: UTF-8
    # 可以支持多个location, 用','隔开
    locations: classpath:db/migration
    # migrate是否校验
    validate-on-migrate: true

在开发时,更多的配置可以从如下SpringBoot AutoConfig中找到。

springboot-flyway-21.png

Migrate配置

这里我们准备两个Versioned Migration

springboot-flyway-25.png
  • V1.0__Init_DB.sql
DROP TABLE IF EXISTS `tb_user`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tb_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(45) NOT NULL,
  `password` varchar(45) NOT NULL,
  `email` varchar(45) DEFAULT NULL,
  `phone_number` int(11) DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
  • V1.1__Init_Data.sql
LOCK TABLES `tb_user` WRITE;
/*!40000 ALTER TABLE `tb_user` DISABLE KEYS */;
INSERT INTO `tb_user` VALUES (1,'pdai','dfasdf','[email protected]',1212121213,'afsdfsaf','2021-09-08 17:09:15','2021-09-08 17:09:15');
/*!40000 ALTER TABLE `tb_user` ENABLE KEYS */;
UNLOCK TABLES;

启动springBootApplication, 我们可以看到如下log

2022-04-13 07:56:56.122  INFO 86030 --- [           main] o.f.c.i.database.base.DatabaseType       : Database: jdbc:mysql://localhost:3306/test_db_flyway (MySQL 8.0)
2022-04-13 07:56:56.220  INFO 86030 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 2 migrations (execution time 00:00.074s)
2022-04-13 07:56:56.245  INFO 86030 --- [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table `test_db_flyway`.`flyway_schema_history` ...
2022-04-13 07:56:56.270  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.282  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.292  INFO 86030 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema `test_db_flyway`: << Empty Schema >>
2022-04-13 07:56:56.297  INFO 86030 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `test_db_flyway` to version "1.0 - Init DB"
2022-04-13 07:56:56.309  WARN 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : DB: Unknown table 'test_db_flyway.tb_user' (SQL State: 42S02 - Error Code: 1051)
2022-04-13 07:56:56.309  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.309  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.310  WARN 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : DB: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous. (SQL State: HY000 - Error Code: 3719)
2022-04-13 07:56:56.310  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.317  WARN 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : DB: Integer display width is deprecated and will be removed in a future release. (SQL State: HY000 - Error Code: 1681)
2022-04-13 07:56:56.317  WARN 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : DB: Integer display width is deprecated and will be removed in a future release. (SQL State: HY000 - Error Code: 1681)
2022-04-13 07:56:56.317  WARN 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : DB: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous. (SQL State: HY000 - Error Code: 3719)
2022-04-13 07:56:56.317  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.318  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.333  INFO 86030 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `test_db_flyway` to version "1.1 - Init Data"
2022-04-13 07:56:56.334  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.335  WARN 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : DB: Table storage engine for 'tb_user' doesn't have this option (SQL State: HY000 - Error Code: 1031)
2022-04-13 07:56:56.335  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.335  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 1 rows affected
2022-04-13 07:56:56.336  WARN 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : DB: Table storage engine for 'tb_user' doesn't have this option (SQL State: HY000 - Error Code: 1031)
2022-04-13 07:56:56.337  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.337  INFO 86030 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : 0 rows affected
2022-04-13 07:56:56.346  INFO 86030 --- [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 2 migrations to schema `test_db_flyway`, now at version v1.1 (execution time 00:00.058s)

生成的flyway更新的记录,test_db_flyway.flyway_schema_history

springboot-flyway-26.png

已经user表结构和数据

springboot-flyway-27.png

进一步理解

通过几个问题,进一步理解。

MySQL的支持性问题

从Flyway对MySQL支持性,可以看出官方期望通过MySQL使用的大量基数获取更多的付费用户。

首先,如果你只是引入flyway-core:8.5.7的包时,会报如下错误

Caused by: org.flywaydb.core.api.FlywayException: Unsupported Database: MySQL 8.0
	at org.flywaydb.core.internal.database.DatabaseTypeRegister.getDatabaseTypeForConnection(DatabaseTypeRegister.java:106) ~[flyway-core-8.5.7.jar:na]
	at org.flywaydb.core.internal.jdbc.JdbcConnectionFactory.<init>(JdbcConnectionFactory.java:76) ~[flyway-core-8.5.7.jar:na]
	at org.flywaydb.core.FlywayExecutor.execute(FlywayExecutor.java:147) ~[flyway-core-8.5.7.jar:na]
	at org.flywaydb.core.Flyway.migrate(Flyway.java:124) ~[flyway-core-8.5.7.jar:na]
	at org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer.afterPropertiesSet(FlywayMigrationInitializer.java:66) ~[spring-boot-autoconfigure-2.5.3.jar:2.5.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) ~[spring-beans-5.3.9.jar:5.3.9]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-5.3.9.jar:5.3.9]
	... 18 common frames omitted

因为找不到内置的Datebase type

springboot-flyway-22.png

所以你应该引入的包是flyway-mysql:8.5.7,而有意思的是这个包中包含的flyway-core版本是7.7.3

springboot-flyway-23.png

然后我们看下官网对MySQL的支持性,这骚操作,5.7版本还需要使用企业版。就是为了收费,折腾...。

springboot-flyway-24.png

https://github.com/realpdai/tech-pdai-spring-demos


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK