[英]Use default and custom liquibase configurations in spring boot application
我想在當前項目中使用兩種Liquibase配置。 我想用於DDL更改的默認配置,第二個用於自定義插入,其中changelog將位於另一個位置。
如果我配置SpringLiquibase
,由於LiquibaseAutoConfiguration
類中的@ConditionalOnClass(SpringLiquibase.class)
注釋,將跳過默認的自動配置。 如何使用默認自動配置+我的自定義? 我可以以某種方式覆蓋@ConditionalOnClass注釋嗎? 或者可能有辦法告訴Liquibase我在應用程序之外還有另一個更改日志,並且僅在它存在的情況下運行它?
謝謝
編輯:
這可能是我的問題的解決方案,但是我在liquibase中加載外部文件(類路徑之外的文件)時遇到問題。
@Configuration
@EnableConfigurationProperties(LiquibaseProperties.class)
public class LiquibaseConfiguration {
@Bean
SpringLiquibase liquibase(DataSource dataSource, LiquibaseProperties properties) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setChangeLog(properties.getChangeLog());
liquibase.setContexts(properties.getContexts());
liquibase.setDataSource(dataSource);
liquibase.setDefaultSchema(properties.getDefaultSchema());
liquibase.setDropFirst(properties.isDropFirst());
liquibase.setShouldRun(properties.isEnabled());
liquibase.setLabels(properties.getLabels());
liquibase.setChangeLogParameters(properties.getParameters());
liquibase.setRollbackFile(properties.getRollbackFile());
return liquibase;
}
@Bean
SpringLiquibase commandInitializerLiquibase(DataSource dataSource,
@Value("${docu.system.initializer.command.liquibase.changeLog}") String changeLogPath,
@Value("${docu.system.initializer.command.liquibase.contexts}") String contexts) {
File changeLog = new File(changeLogPath);
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setContexts(contexts);
liquibase.setIgnoreClasspathPrefix(true);
liquibase.setChangeLog(changeLog.getAbsolutePath());
liquibase.setShouldRun(changeLog.exists());
//liquibase.setResourceLoader(liquibaseResourceLoader());
addPathToClassloader(changeLogPath);
return liquibase;
}
}
如果您想使用Spring Boot自動配置的Liquibase功能,那么您的上下文中只能有一個SpringLiquibase
bean。 這是因為LiquibaseAutoConfiguration
類中的@ConditionalOnMissingBean(SpringLiquibase.class)
注釋。 Spring的條件特性搜索SpringLiquibase
實例及其子類實例,因此擴展SpringLiquibase
類不會解決該問題。
沒有好辦法覆蓋LiquibaseAutoConfiguration
。 在這種情況下,您有3個解決方案可以解決您的問題:
1)實現兩個單獨的Liquibase bean配置:
@Configuration
public class LiquibaseConfiguration {
@Autowired
private DataSource dataSource;
//define this property in your embedded properties file or use spring's default
@Value("${liquibase.change-log}")
private String defaultLiquibaseChangelog;
@Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog(defaultLiquibaseChangelog);
// Configure rest of liquibase here...
// ...
return liquibase;
}
}
和
@Configuration
public class LiquibaseConfiguration2 {
@Autowired
private DataSource dataSource;
//optional, define it in external configuration or through command line param
@Value("${liquibase.change-log-additional:#{null}}")
private String additionalLiquibaseChangelog;
@Bean(name = "additionalLiquibase")
public SpringLiquibase liquibase() {
if (additionalLiquibaseChangelog != null) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog(additionalLiquibaseChangelog);
// Configure rest of liquibase here...
// ...
return liquibase;
}
return null;
}
}
2)使用Liquibase
而不是SpringLiquibase
來手動配置liquibase實例
使用一個自動配置的SpringLiquibase
和一個純Liquibase
配置而不是SpringLiquibase
(您需要手動運行遷移並處理SpringLiquibase
實現的其他內容)
3)僅使用一個SpringLiquibase實例
使用Liquibase的changelogParameters
( http://www.liquibase.org/documentation/changelog_parameters.html ), include
標簽( http://www.liquibase.org/documentation/include.html )和一個SpringLiquibase
實例的組合。
示例實現:
Liquibase bean配置
@Configuration
public class LiquibaseConfiguration {
@Autowired
private DataSource dataSource;
//define this property in your embedded properties file or use spring's default
@Value("${liquibase.change-log}")
private String defaultLiquibaseChangelog;
//define this property in your embedded properties file
@Value("${liquibase.extended-change-log}")
private String extendedLiquibaseChangelog;
//optional, define it in external configuration or through command line param
@Value("${liquibase.data-change-log:#{null}}")
private String liquibaseDataChangelog;
@Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
if (liquibaseDataChangelog != null) {
//here you can check if file exists...
Map<String, String> liquibaseChangelogParameters = new HashMap<>();
liquibaseChangelogParameters.put("liquibaseExternalDataChangelogPath", liquibaseDataChangelog);
liquibase.setChangeLog(extendedLiquibaseChangelog);
liquibase.setChangeLogParameters(liquibaseChangelogParameters);
} else {
liquibase.setChangeLog(defaultLiquibaseChangelog);
}
// Configure rest of liquibase here...
// ...
return liquibase;
}
}
changelog.xml(liquibase.change-log)
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd">
<include relativeToChangelogFile="true" file="changelog-master.xml"/>
</databaseChangeLog>
changelog-with-external-data.xml(liquibase.extended-change-log)
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd">
<include relativeToChangelogFile="true" file="changelog-master.xml"/>
<include relativeToChangelogFile="false" file="${liquibaseDataChangelogPath}"/>
</databaseChangeLog>
請記住,單獨更改日志可能很危險。 您必須確保您的更改日志是獨立的:
包含的更改日志按找到的順序運行,因此需要注意確保包含的更改日志完全獨立,或者首先運行所需的更改日志。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.