SpringBoot使用flyway初始化數(shù)據(jù)庫
概述
Flyway這款數(shù)據(jù)庫版本工具就算大家沒有使用過但也略有耳聞了,SpringBoot對該款工具進行集成的框架可以讓我們在啟動SpringBoot應(yīng)用時自動去找SQL版本文件進行比對執(zhí)行,但在遷移或初始化時往往還是需要先手動進行下數(shù)據(jù)庫的初始化配置,否則會把Unknown database的異常。 為了減少這一步所以個人就以SpringBoot的方式編碼在項目的啟動時自動進行數(shù)據(jù)庫的初始化,然后再執(zhí)行版本文件。
自動建庫實現(xiàn)步驟
具體思路
- SpringBoot的配置項都會有相應(yīng)的Properties屬性類,數(shù)據(jù)庫的屬性類為DataSourceProperties,flyway的屬性類為FlywayProperties,盡可能的使用其中的配置項而不額外添加自定義的配置
- 建庫與相關(guān)設(shè)置的語句一般不會對已存在的設(shè)置進行更改(如建庫建表時都是CREATE xxx IF NOT EXISTS),所以項目初始化時每次都執(zhí)行也不會影響現(xiàn)有的數(shù)據(jù)庫配置,編碼時可以不用添加執(zhí)行的前置判斷
代碼實現(xiàn)
配置文件
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;
為了讓項目的配置結(jié)構(gòu)更清晰,所以我把數(shù)據(jù)庫的相關(guān)配置都獨立到application-database.yml
中。
flyway的init-sqls
配置是當(dāng)獲取到SQL statement時會執(zhí)行SQL語句列表,但需要注意的是如果spring.datasource.url
連接不上,該塊語句是依舊無法被執(zhí)行的,因為SpringBoot集成的flyway配置是通過spring.datasource
的配置去連接數(shù)據(jù)庫的,如果url中的數(shù)據(jù)庫不存在,flyway的版本遷移就無法執(zhí)行了。
前文提到盡可能的使用SpringBoot原有的配置項,所以init-sqls
其實是我配給自己用的。 個人通過init-sqls配置初始化語句與其它方式配置初始化想到的好處:
- 無需將初始化語句硬編碼再讓Statement執(zhí)行
- 當(dāng)數(shù)據(jù)庫選型進行變更時只需再配置文件中進行修改相應(yīng)的初始化語句
- SpringBoot可以直接以字符串列表進行讀取,開發(fā)過程中使用起來更加靈活,而不用去解析SQL文件
數(shù)據(jù)庫初始化器DatabaseInitializer
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?參數(shù) int lastSplitIndex = url.lastIndexOf('/'); // 獲取spring.datasource.url具體數(shù)據(jù)庫schema前的jdbc url String addressUrl = url.substring(0, lastSplitIndex); // 直連數(shù)據(jù)庫地址: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配置進行建庫與數(shù)據(jù)庫配置 // executeUpdate:執(zhí)行給定的SQL語句,該語句可以是INSERT,UPDATE或DELETE語句或不返回任何內(nèi)容的SQL語句,例如SQL DDL語句。 statement.executeUpdate(sql); } statement.close(); connection.close(); dataSource.close(); log.info("DatabaseInitializer initialize completed"); } }
簡單的主程序FlywayApplication
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); } }
執(zhí)行效果圖
當(dāng)項目啟動時可以看到DatabaseInitializer
會先通過init-sqls
進行數(shù)據(jù)庫的初始化,然后SpringBoot再初始化通用的數(shù)據(jù)源并執(zhí)行SQL版本文件。圖中的create_database.sql文件存放的是init-sqls
配置的語句,該文件不會被執(zhí)行,可以忽略。
附
- 如果對flyway不了解的可以看我之前的文章SpringBoot集成Flyway進行數(shù)據(jù)庫版本遷移管理
- 本文例子倉庫:spring-bootflyway-demo
- flyway官網(wǎng)文檔
以上就是SpringBoot使用flyway初始化數(shù)據(jù)庫的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot 初始化數(shù)據(jù)庫的資料請關(guān)注腳本之家其它相關(guān)文章!
- SpringBoot整合Flyway的方法(數(shù)據(jù)庫版本遷移工具)
- Flyway詳解及Springboot集成Flyway的詳細(xì)教程
- SpringBoot整合flyway實現(xiàn)步驟解析
- SpringBoot整合flyway實現(xiàn)自動創(chuàng)建表的方法
- SpringBoot項目集成Flyway詳細(xì)過程
- SpringBoot使用Flyway進行數(shù)據(jù)庫管理的操作方法
- SpringBoot使用Flyway進行數(shù)據(jù)庫遷移的實現(xiàn)示例
- springboot配置flyway(入門級別教程)
- spring boot整合flyway實現(xiàn)數(shù)據(jù)的動態(tài)維護的示例代碼
相關(guān)文章
Java 字節(jié)數(shù)組類型(byte[])與int類型互轉(zhuǎn)方法
下面小編就為大家?guī)硪黄狫ava 字節(jié)數(shù)組類型(byte[])與int類型互轉(zhuǎn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02Spring @Cacheable自定義緩存過期時間的實現(xiàn)示例
本文主要介紹了Spring @Cacheable自定義緩存過期時間的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05Spring中@PropertySource和@Value注解詳解
這篇文章主要介紹了Spring中@PropertySource和@Value注解詳解,@PropertySource注解可以方便和靈活的向Spring的環(huán)境容器(org.springframework.core.env.Environment Environment)中注入一些屬性,這些屬性可以在Bean中使用,需要的朋友可以參考下2023-11-11SpringBoot實現(xiàn)EMQ設(shè)備的上下線告警
EMQX?的上下線系統(tǒng)消息通知功能在客戶端連接成功或者客戶端斷開連接,需要實現(xiàn)設(shè)備的上下線狀態(tài)監(jiān)控,所以本文給大家介紹了如何通過SpringBoot實現(xiàn)EMQ設(shè)備的上下線告警,文中有詳細(xì)的代碼示例,需要的朋友可以參考下2023-10-10SpringBoot+WebSocket實現(xiàn)IM及時通訊的代碼示例
項目中碰到需要及時通訊的場景,使用springboot集成websocket,即可實現(xiàn)簡單的及時通訊,本文介紹springboot如何集成websocket、IM及時通訊需要哪些模塊、開發(fā)和部署過程中遇到的問題、以及實現(xiàn)小型IM及時通訊的代碼,需要的朋友可以參考下2023-10-10Spring boot + mybatis + Vue.js + ElementUI 實現(xiàn)數(shù)據(jù)的增刪改查實例代碼(一)
這篇文章主要介紹了Spring boot + mybatis + Vue.js + ElementUI 實現(xiàn)數(shù)據(jù)的增刪改查實例代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-05-05