Skip to main content
 首页 » 编程设计

在Spring Boot中使用Flyway迁移数据库

2022年07月19日119cloudgamer

在Spring Boot中使用Flyway迁移数据库

第一次总不会是完美的。新系统的数据库结构满足应用,但随着应用深入,需要满足新的需求并增加新的特性。
Flyway是实现对数据库结构改变实现版本控制的工具,让你很容易、可靠地迁移至新的版本。本文我们学习在Spring Boot中如何管理数据库的变化。

我们新建示例应用进行说明,Spring Boot应用使用MySQL Database & Spring Data JPA, 学习如何集成Flyway.

创建应用

新建Spring Boot应用,可以在ide中或在spring官网上。依赖下列模块web,mysql,data-jpa,flyway。

配置数据库

首先创建新的数据库命名为flyway_demo(名称可以自定义)。然后配置src/main/application.properties,在文件中增加下列属性:

## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) 
spring.datasource.url = jdbc:mysql://localhost:3306/flyway_demo?useSSL=false 
spring.datasource.username = root 
spring.datasource.password = root 
 
## Hibernate Properties 
# The SQL dialect makes Hibernate generate better SQL for the chosen database 
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect 
 
## This is important 
# Hibernate ddl auto (create, create-drop, validate, update) 
spring.jpa.hibernate.ddl-auto = validate 

读者需要修改自己的数据库用户名和密码。spring.jpa.hibernate.ddl-auto属性很重要。其会根据应用中创建的实体类验证数据库schema,如果schema不匹配实体规范会抛出错误。

创建实体类

创建实体类,为了可以创建并测试flyway迁移实体对应表。首先创建包domain,然后新建User.java类。

package com.dataz.flyway.domain; 
 
import lombok.Getter; 
import lombok.Setter; 
 
import javax.persistence.*; 
import javax.validation.constraints.NotBlank; 
import javax.validation.constraints.Size; 
 
@Entity 
@Table(name = "users") 
@Setter 
@Getter 
public class User { 
  @Id 
  @GeneratedValue(strategy = GenerationType.IDENTITY) 
  private Long id; 
 
  @NotBlank 
  @Column(unique = true) 
  @Size(min = 1, max = 100) 
  private String username; 
 
  @NotBlank 
  @Size(max = 50) 
  private String firstName; 
 
  @Size(max = 50) 
  private String lastName; 
} 

创建Flyway迁移脚本

flyway默认会读取classpath:db/migration目录下迁移脚本。所有迁移脚本必须遵循特定名称约定————V<版本号>_<名称>.sql 。读者可以查看官网了解更多命名规范。

现在开始创建第一个数据库迁移脚本。首先在src/main/resources下创建db/migration目录。

mkdir -p src/main/resources/db/migration 

在 src/main/resources/db/migration 目录中新增V1__init.sql文件,内容如下:

CREATE TABLE users ( 
  id bigint(20) NOT NULL AUTO_INCREMENT, 
  username varchar(100) NOT NULL, 
  first_name varchar(50) NOT NULL, 
  last_name varchar(50) DEFAULT NULL, 
  PRIMARY KEY (id), 
  UNIQUE KEY UK_username (username) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

现在第一次启动应用,你将会看到下面日志信息,已经成功迁移schema至版本 1 - init。
在这里插入图片描述

Flyway如何实现迁移

当第一次运行时,flyway创建flyway_schema_history表,然后在表中存储必要的版本迁移元信息。

mysql> show tables; 
+-----------------------+ 
| Tables_in_flyway_demo | 
+-----------------------+ 
| flyway_schema_history | 
| users                 | 
+-----------------------+ 
2 rows in set (0.00 sec) 

检查flyway_schema_history表的内容:

mysql> select * from flyway_schema_history; 
+----------------+---------+-------------+------+--------------+------------+--------------+---------------------+----------------+---------+ 
| installed_rank | version | description | type | script       | checksum   | installed_by | installed_on        | execution_time | success | 
+----------------+---------+-------------+------+--------------+------------+--------------+---------------------+----------------+---------+ 
|              1 | 1       | init        | SQL  | V1__init.sql | 1952043475 | root         | 2018-03-06 11:25:58 |             16 |       1 | 
+----------------+---------+-------------+------+--------------+------------+--------------+---------------------+----------------+---------+ 
1 row in set (0.00 sec) 

表中存储了当前迁移版本、脚本文件名称、文件校验码以及其他信息。当运行应用程序时,Flyway首先通过校验码验证已经迁移的脚本和表中存储的元数据是否一致。所以,如果V1__init.sql完成迁移后被修改,Flyway会抛出错误,运维校验信息不匹配。

因此,schema有任何改变,需要创建新的迁移脚本文件,并使用新的版本命名文件:V2__.sql,让flyway感知并执行。

增加迁移任务

下面创建另一个迁移脚本,验证flyway自动迁移数据库至新的版本。在目录src/main/resources/db/migration中创建新的脚本V2__testdata.sql,增加以下内容:

INSERT INTO users(username, first_name, last_name) VALUES('callicoder', 'Rajeev', 'Singh'); 
INSERT INTO users(username, first_name, last_name) VALUES('flywaytest', 'Flyway', 'Test'); 

如果你现在运行应用,flyway会检测到新的迁移脚本,并迁移数据库至最新版本。
在这里插入图片描述
打开users表,可以看到有两条记录:

mysql> select * from users; 
+----+------------+-----------+------------+ 
| id | first_name | last_name | username   | 
+----+------------+-----------+------------+ 
|  4 | Rajeev     | Singh     | callicoder | 
|  5 | Flyway     | Test      | flywaytest | 
+----+------------+-----------+------------+ 
2 rows in set (0.01 sec) 

同时,flyway在元数据表中也存储新的schema版本:

mysql> select * from flyway_schema_history; 
+----------------+---------+-------------+------+------------------+-------------+--------------+---------------------+----------------+---------+ 
| installed_rank | version | description | type | script           | checksum    | installed_by | installed_on        | execution_time | success | 
+----------------+---------+-------------+------+------------------+-------------+--------------+---------------------+----------------+---------+ 
|              1 | 1       | init        | SQL  | V1__init.sql     |  1952043475 | root         | 2018-03-06 11:25:58 |             16 |       1 | 
|              2 | 2       | testdata    | SQL  | V2__testdata.sql | -1926058189 | root         | 2018-03-06 11:25:58 |              6 |       1 | 
+----------------+---------+-------------+------+------------------+-------------+--------------+---------------------+----------------+---------+ 
2 rows in set (0.00 sec) 

总结

本文介绍了如何在spring boot中整合flyway进行数据库schema迁移及版本控制。在实际项目中可以避免手动修改脚本麻烦,提高项目升级效率。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/86715198