Flyway这款数据库版本工具就算大家没有使用过但也略有耳闻了,SpringBoot对该款工具进行集成的框架可以让我们在启动SpringBoot应用时自动去找SQL版本文件进行比对执行,但在迁移或初始化时往往还是需要先手动进行下数据库的初始化配置,否则会把Unknown database的异常。 为了减少这一步所以个人就以SpringBoot的方式编码在项目的启动时自动进行数据库的初始化,然后再执行版本文件。
配置文件
spring: profiles: include: database
application-database.yml
spring: datasource: url: jdbc:mysql://yourIp:3306/spring_boot_series?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=GMT username: yourUsername password: yourPassword driver-class-name: com.mysql.cj.jdbc.Driver # 自动读取spring.datasource配置进行迁移操作 flyway: # 版本迁移位置 locations: classpath:db baseline-version: 1.0.2 init-sqls: - SET @OLD_UNIQUE_CHECKS = @@UNIQUE_CHECKS, UNIQUE_CHECKS = 0; - SET @OLD_FOREIGN_KEY_CHECKS = @@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS = 0; - SET @OLD_SQL_MODE = @@SQL_MODE, SQL_MODE = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; - CREATE SCHEMA IF NOT EXISTS `spring_boot_series` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
为了让项目的配置结构更清晰,所以我把数据库的相关配置都独立到application-database.yml中。
flyway的init-sqls配置是当获取到SQL statement时会执行SQL语句列表,但需要注意的是如果spring.datasource.url连接不上,该块语句是依旧无法被执行的,因为SpringBoot集成的flyway配置是通过spring.datasource的配置去连接数据库的,如果url中的数据库不存在,flyway的版本迁移就无法执行了。
前文提到尽可能的使用SpringBoot原有的配置项,所以init-sqls其实是我配给自己用的。 个人通过init-sqls配置初始化语句与其它方式配置初始化想到的好处:
package io.wilson.flyway; import com.zaxxer.hikari.HikariDataSource; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.flyway.FlywayProperties; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; /** * @author Wilson */ @Slf4j @Component @AllArgsConstructor public class DatabaseInitializer { private final FlywayProperties flywayProperties; private final DataSourceProperties dataSourceProperties; @PostConstruct public void init() throws SQLException { log.info("DatabaseInitializer uses flyway init-sqls to initiate database"); String url = dataSourceProperties.getUrl(); // jdbc url最后一个 '/' 用于分割具体 schema?参数 int lastSplitIndex = url.lastIndexOf('/'); // 获取spring.datasource.url具体数据库schema前的jdbc url String addressUrl = url.substring(0, lastSplitIndex); // 直连数据库地址:jdbc:mysql://yourIp:port HikariDataSource dataSource = new HikariDataSource(); dataSource.setJdbcUrl(addressUrl); dataSource.setUsername(dataSourceProperties.getUsername()); dataSource.setPassword(dataSourceProperties.getPassword()); Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement(); for (String sql : flywayProperties.getInitSqls()) { // 通过flyway的init-sqls配置进行建库与数据库配置 // executeUpdate:执行给定的SQL语句,该语句可以是INSERT,UPDATE或DELETE语句或不返回任何内容的SQL语句,例如SQL DDL语句。 statement.executeUpdate(sql); } statement.close(); connection.close(); dataSource.close(); log.info("DatabaseInitializer initialize completed"); } }
package io.wilson.flyway; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author Wilson */ @SpringBootApplication @MapperScan("io.wilson.flyway.mapper") public class FlywayApplication { public static void main(String[] args) { SpringApplication.run(FlywayApplication.class, args); } }
当项目启动时可以看到DatabaseInitializer会先通过init-sqls进行数据库的初始化,然后SpringBoot再初始化通用的数据源并执行SQL版本文件。图中的create_database.sql文件存放的是init-sqls配置的语句,该文件不会被执行,可以忽略。
以上就是SpringBoot使用flyway初始化数据库的详细内容,更多关于SpringBoot 初始化数据库的资料请关注呐喊教程其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#nhooo.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。