在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