SpringBoot整合Flyway
SpringBoot整合Flyway数据库版本迁移工具使用
Flyway官方文档:https://flywaydb.org/documentation/
使用感想:数据库的传统部署到自动化部署,工具的便利性使的开发更具效率性!
简介:Flyway是一个开源数据库迁移工具。与配置相比,它极力主张简单和约定。七个基本命令:Migrate(迁移)、Clean(清理)、Info(信息)、Validate(校验)、Undo(撤销)、Baseline(基准线)、Repair(修复)
注意:数据库版本低版本可能不支持
使用步骤
1、pom依赖(另需jdbc(spring-boot-starter-data-jdbc)、mysql驱动依赖)
<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency>
2、配置(更详细配置可深入官网,例子mysql )
spring: flyway: enabled: true #是否开启 validate-on-migrate: true # 迁移前校验 SQL 文件是否存在问题 clean-disabled: true # 生产环境一定要关闭 是否要清除schema:表,索引,视图,存储过程.默认清理false 不清理-true check-location: true # 校验路径下是否存在 SQL 文件 baseline-on-migrate: true # 最开始已经存在表结构,且不存在 flyway_schema_history 表时,需要设置为 true baseline-version: 0 # 基础版本 0 locations: classpath:db/migration #默认路径 resources目录下新建 table: flyway_schema_history #配置数据库信息表的名称 datasource: url: jdbc:mysql://127.0.0.1:3306/db01?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai # JDBC版本和MYSQL版本不兼容需要加上 useSSL=true username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver
postgresql配置
spring: flyway: enabled: true # 是否启用flyway encoding: UTF-8 # 编码格式,默认UTF-8 locations: classpath:db/migration # 迁移sql脚本文件存放路径,默认db/migration sqlMigrationPrefix: V # 迁移sql脚本文件名称的前缀,默认V sqlMigrationSeparator: __ # 迁移sql脚本文件名称的分隔符,默认2个下划线__ sqlMigrationSuffixes: .sql # 迁移sql脚本文件名称的后缀 validateOnMigrate: true # 迁移时是否进行校验,默认true baselineOnMigrate: true # 设置为true,当迁移发现数据库非空且存在没有元数据的表时,自动执行基准迁移,新建schema_version表 schemas: public # postgres10没有引入这个不提示错误,postgres12没有引入会报错 模式选择 public/myschema datasource: url: jdbc:postgresql://127.0.0.1:5432/pg_demo?currentSchema #=schemas username: postgres password: 123456 driver-class-name: org.postgresql.Driver
3、静态文件下db/migration的脚本配置
a、sql命名:V<VERSION>__<NAME>.sql
例:V1_0__INIT.sql (大写V,版本1.0,描述INIT,类型sql)
b、对应的数据库sql语句正确
---------------------------------------------------------------以上已完成数据库版本迁移
4、初始化新建数据库
a、有的不是springboot项目可以写个工具类运行时初始化
b、启动 ServletContextAware 或 ServletContextListener 重新初始化,如下:
@Component @Slf4j public class FlywayConfig implements ServletContextAware { @Value("${spring.datasource.url}") public String url; @Value("${spring.datasource.username}") public String username; @Value("${spring.datasource.password}") public String password; @Override public void setServletContext(ServletContext servletContext) { log.info("在填充普通bean属性之后但在初始化之前调用setServletContext方法"); try { String datasourceName = url.substring(0, url.indexOf("?")).substring(url.substring(0, url.indexOf("?")).lastIndexOf("/") + 1); String dbUrl = url.replace(datasourceName, ""); Connection connection = DriverManager.getConnection(dbUrl, username, password); // 连接已经存在的数据库,如:mysql Statement statement = connection.createStatement(); // 不存在则创建数据库 statement.executeUpdate("CREATE DATABASE IF NOT EXISTS `" + datasourceName + "` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"); statement.close(); connection.close(); } catch(Exception e) { e.printStackTrace(); System.exit(-1);//非正常退出程序 0-正常 log.error("数据库创建失败"); } // Flyway flyway = Flyway.configure().dataSource(url, user, password).baselineOnMigrate(true).load(); //flyway.migrate();//除了配置外代码执行法 } }
c、pgsql创建数据库
ResultSet rs=statement.executeQuery("SELECT u.datname FROM pg_catalog.pg_database u where u.datname='"+datasourceName+"';"); String datname = null; while(rs.next()) { datname=rs.getString("datname"); } if(StringUtils.isEmpty(datname)){ statement.executeUpdate("CREATE DATABASE " + datasourceName + ";"); }