1. 程式人生 > 程式設計 >springboot 啟動時初始化資料庫的步驟

springboot 啟動時初始化資料庫的步驟

問題描述

在spring-boot啟動時,希望能執行相應的sql檔案來初始化資料庫。

使用配置檔案初始化資料庫

可以在spring-boot的配置檔案application.yml中設定要初始化的sql檔案。這是最簡單的方法,只需要新增屬性就可以實現。

首先設定spring.datasource.initialization-mode=always表示任何型別資料庫都進行資料庫初始化,預設情況下,spring-boot會自動載入data.sql或data-${platform}.sql檔案來初始化資料庫。可以通過設定不同的資料庫平臺來改變啟動的指令碼名稱。

例如設定spring.datasource.platform=mysql,就會載入data-mysql.sql的資料庫指令碼。把資料庫指令碼檔案放在resources路徑下即可。

如果專案使用的是flyway管理資料庫的話,可以直接在flyway路徑下新增一個新版本的sql檔案,flyway也會自動執行sql檔案並記錄版本資訊。

通過程式碼初始化資料庫

如果通過配置檔案不能滿足需求,可以通過程式碼來初始化資料庫。
只需要提供DataSourceInitializer這個bean,spring-boot啟動時就會根據DataSourceInitializer來初始化資料庫了。

@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
  ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
  resourceDatabasePopulator.addScript(new ClassPathResource("/data.sql"));
  DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
  dataSourceInitializer.setDataSource(dataSource);
  dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
  return dataSourceInitializer;
}

在此基礎上,我們可以自定義註解,通過獲取註解上的sql檔案路徑,來達到通過註解初始化資料庫目的,這樣更方便簡潔。
首先定義註解InitDataSource:

/** 
 * 用於補充:Hibernate無法自動建立檢視的缺陷。 
 * 系統啟動時(hibernate根據entity建立完基本的資料表後),開始執行本註解下的sql檔案中的SQL語言。 
 * 使用方法: 
 * @InitDataSource("sql檔案路徑(相對於resources路徑下)") ---- 註解到對應的類上 
 * 比如:@InitDataSource("db/view/createView.sql)") 
 * 使用示例請參見:ResourceApplication.java 
 * 預瞭解詳細的實現過程請參考:WebConfig.java 的 dataSourceInitializer方法 
 * @author huangtingxiang 
 */
@Target({ElementType.TYPE})   // 該註解用於類上 
@Retention(RetentionPolicy.RUNTIME) // 在執行時起作用 
@Component 
public @interface InitDataSource { 
  String\[\] value(); 
}

然後通過ClassPathScanningCandidateComponentProvider這個類來掃描spring元件上InitDataSource註解的值,將值取出,新增到DataSourceInitializer的初始化指令碼中:

@Bean 
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) { 
  ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator(); 
  // 掃描com.mengyunzhi.measurement 包 找到InitDataSource註解的類(註解需使用到實現類上) 
 ClassPathScanningCandidateComponentProvider provider 
      = new ClassPathScanningCandidateComponentProvider(false); 
  provider.addIncludeFilter(new AnnotationTypeFilter(InitDataSource.class)); //新增包含的過濾資訊 
 for (BeanDefinition beanDef : provider.findCandidateComponents("com.mengyunzhi.measurement")) { 
    Class<?> cl = null; 
    try { 
      cl = Class.forName(beanDef.getBeanClassName()); 
      InitDataSource initDataSource = cl.getAnnotation(InitDataSource.class); 
      String\[\] sqlFiles = initDataSource.value(); 
      for (String sql: sqlFiles) { 
        // 如果sql檔案存在 加入資料庫初始化中 否則丟擲異常終止執行 
 ClassPathResource resource = new ClassPathResource("/" + sql); 
        if (resource.exists()) { 
          resourceDatabasePopulator.addScript(resource); 
        } else { 
          throw new DataSourceInitializerException("未找到資原始檔:" + sql,cl); 
        } 
      } 
    } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
    } 
  } 
  DataSourceInitializer dataSourceInitializer = new DataSourceInitializer(); 
  dataSourceInitializer.setDataSource(dataSource); 
  dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator); 
  return dataSourceInitializer; 
}

這樣一來,只需要在spring-boot類上使用@InitDataSource({"data.sql"})註解,就可以自動進行資料庫的初始化操作了。

以上就是springboot 啟動時初始化資料庫的步驟的詳細內容,更多關於springboot 初始化資料庫的資料請關注我們其它相關文章!