项目中接入 flyway 的几种方式
自己整理了几种实现方式~
欢迎吐槽和交流~
本篇实战篇,话不多说,直接开刚~
注:最终的源码也会给出,放在文章最下方了
方式一:使用配置类读取数据库配置
pom 文件中引入 flyway 依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>6.0.7</version>
<!--<version>5.0.3</version>-->
</dependency>
yml 文件中的配置如下(可以将配置信息放在 配置中心里):
spring:
application:
name: flyway-db
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_user?useUnicode=true&useSSL=false&characterEncoding=utf-8
username: tester
password: balabala
新增配置类:
FlywayConfiguration.java
package com.example.flywaydb.config;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.configuration.ClassicConfiguration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 描述: <br>
* < TODO >
*
* @author qacboy
* @create 2019-10-23
* @since TODO
*/
@Configuration
public class FlywayConfiguration {
@Value("${spring.datasource.url}")
private String datasourceUrl;
@Value("${spring.datasource.username}")
private String databaseUsername;
@Value("${spring.datasource.password}")
private String databasePassword;
// 脚本存放路径
// @Value("${flyway.locations}")
// private String locations;
/**
* version: 6.0.7 写法
*/
@Bean
Flyway flyway() {
ClassicConfiguration classicConfiguration = new ClassicConfiguration();
classicConfiguration.setDataSource(datasourceUrl, databaseUsername, databasePassword);
classicConfiguration.setBaselineOnMigrate(true);
// classicConfiguration.setLocations(locations);
Flyway flyway = new Flyway(classicConfiguration);
System.out.println(" ****** repair ****** ");
flyway.repair();
System.out.println(" ****** migrate ****** ");
flyway.migrate();
return flyway;
}
/**
* repair
* migrate
* version: 5.0.3 写法
* @return
*/
/*
@Bean(initMethod = "migrate")
@Bean
Flyway flyway() {
Flyway flyway = new Flyway();
flyway.setBaselineOnMigrate(true);
flyway.setDataSource(datasourceUrl, databaseUsername, databasePassword);
// flyway.setLocations(locations);
System.out.println(" ****** repair");
flyway.repair();
System.out.println(" ****** migrate");
flyway.migrate();
return flyway;
}*/
}
注:添加数据库脚本,脚本存放位置(默认):src/resources/db/migration(目录是可以自定义的,参数由 FlywayConfiguration.java 中的 locations 控制)
SQL 脚本的命名规则( 这里我的写法只是提供一个参考 ):
不可重复执行脚本:
V${version}__${name}.sql
,其中前缀V、后缀.sql、分隔符__;
可重复执行脚本:
R__${name}.sql
,其中前缀V、后缀.sql、分隔符__;
当然,你也可以在配置类中自行修改匹配规则
SQL 脚本一并给出:
CREATE TABLE user_test (
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=utf8mb4 COLLATE=utf8mb4_general_ci;
启动项目,坐等执行成功~
如果你只想执行单个命令
emmm… 写个测试类吧(突然变 low 有没有,哈哈哈)
顺便把测试类给了
package com.example.flywaydb;
import com.alibaba.fastjson.JSONObject;
import org.flywaydb.core.Flyway;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* 描述: <br>
* < TODO >
*
* @author qacboy
* @create 2019-10-23
* @since TODO
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class FlywayTest {
@Autowired
private Flyway flyway;
@Test
public void dbMigrate() {
System.out.println(flyway.migrate());
}
@Test
public void dbValidate() {
flyway.validate();
}
@Test
public void dbClean() {
flyway.clean();
}
@Test
public void dbInfo() {
System.out.println(JSONObject.toJSONString(flyway.info()));
}
@Test
public void dbBaseline() {
flyway.baseline();
}
@Test
public void dbRepair() {
flyway.repair();
}
}
好了,至此方式一介绍已经结束,项目也成功引入 flyway 了,so easy !
方式二:使用脚本
下载脚本
根据需要选择合适的系统,下载 flyway 官方提供的脚本 。
然后,
官网教程已经写得很清清楚楚明明白白了~~
跟着来就行了
修改配置文件
简单起见~
我这里也就只修改的 flyway.conf 文件了,当然你也可以自定义配置文件的位置和名称,这里为了方便就直接使用默认的配置文件了
然后配置好数据库的连接信息即可
这种方式的使用也简单~
可以将脚本放在你的服务器上,需要对数据库进行更新的时候,把你的脚本拷贝至你的指定目录,然后再去执行一下 flyway 的脚本命令就行了
执行 flyway 命令
直接执行 flyway 命令(注意:需要进到脚本的目录下)
sh flyway migrate
感觉最常用的命令也就是 repair 和 migrate 这两个了
一般也是配合着使用,先 repair 再 migrate
好了,完美搞定~
方式三:通过 flyway 官网提供的插件
这个方法就更更更简单了~
不过~
不推荐使用,
不推荐使用,
不推荐使用!
因为需要将数据库的配置信息定义在 pom 文件中,这样很不安全
反正都说是介绍了,那就一起说一下~
引入插件
在 pom 文件中引入 flyway 插件,同时配置数据库信息
<!--直接使用 plugin 的配置-->
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<configuration>
<url>jdbc:mysql://localhost:3306/db_user?useUnicode=true&useSSL=false&characterEncoding=utf-8</url>
<user>tester</user>
<password>balabala</password>
</configuration>
</plugin>
点击运行插件
在 plugin 中点击 flyway -> migrate ,ok 坐等插件执行成功~
注:脚本存放位置(同方式一):src/resources/db/migration
大功告成!
方式四
还有一种刺激的写法(炒鸡不推荐):
封装成请求:暴露出去
前期所有步骤同方式一
新增 service 和 controller 即可
这里一并给出了~
IFlywayDBService.java
package com.example.flywaydb.service;
import org.flywaydb.core.api.MigrationInfoService;
/**
* 描述: <br>
* < TODO >
*
* @author qacboy
* @create 2019-10-23
* @since TODO
*/
public interface IFlywayDBService {
/**
* 数据迁移,新增数据脚本时,执行 migrate 进行更新
*/
int dbMigrate();
/**
* 校验数据中是否有执行失败的脚本,当有执行失败的时候,执行 repair 进行修复
*/
void dbValidate();
/**
* 警告: 删除 数据库 中所有的表
* 谨慎操作!!!
* 传说中的删库跑路
*/
void dbClean();
MigrationInfoService dbInfo();
void dbBaseline();
/**
* 清除数据中执行失败的脚本记录
*/
void dbRepair();
}
FlywayDBServiceImpl.java
package com.example.flywaydb.service.impl;
import com.example.flywaydb.service.IFlywayDBService;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.MigrationInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 描述: <br>
* < TODO >
*
* @author qacboy
* @create 2019-10-23
* @since TODO
*/
@Service
public class FlywayDBServiceImpl implements IFlywayDBService {
@Autowired
private Flyway flyway;
@Override
public int dbMigrate() {
System.out.println("dbMigrate");
return flyway.migrate();
}
@Override
public void dbValidate() {
System.out.println("dbValidate");
flyway.validate();
}
@Override
public void dbClean() {
System.out.println("dbClean");
flyway.clean();
}
@Override
public MigrationInfoService dbInfo() {
System.out.println("dbInfo");
return flyway.info();
}
@Override
public void dbBaseline() {
System.out.println("dbBaseline");
flyway.baseline();
}
@Override
public void dbRepair() {
System.out.println("dbRepair");
flyway.repair();
}
}
FlywayDBController.java
package com.example.flywaydb.controller;
import com.example.flywaydb.service.IFlywayDBService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 描述: <br>
* < TODO >
*
* @author qacboy
* @create 2019-10-23
* @since TODO
*/
@RestController
public class FlywayDBController {
@Autowired
private IFlywayDBService flyway;
@GetMapping(value = "/migrate")
public void dbMigrate() {
System.out.println("migrate");
flyway.dbMigrate();
}
@GetMapping(value = "/validate")
public void dbValidate() {
System.out.println("validate");
flyway.dbValidate();
}
@GetMapping(value = "/clean")
public void dbClean() {
System.out.println("clean");
flyway.dbClean();
}
@GetMapping(value = "/info")
public void dbInfo() {
System.out.println("info");
flyway.dbInfo();
}
@GetMapping(value = "/baseline")
public void dbBaseline() {
System.out.println("baseline");
flyway.dbBaseline();
}
@GetMapping(value = "/repair")
public void dbRepair() {
System.out.println("repair");
flyway.dbRepair();
}
}
目录结构如下:
方式五
感觉最满意的写法:
自己写个插件去封装,flyway 的操作。
emmm… 抱歉,能力有限 。 idea 的插件编写还不会整,有时间研究下再去搞一个玩玩
写的不好的地方还请大伙多多包涵哈~
要是能帮忙指出更是十分感谢了!
要是有写得不清不楚的地方,也欢迎小伙伴们来交流呀~
项目地址: https://github.com/QACBoy/flywaydb
参考文章:
https://flywaydb.org/documentation/command/migrate