我想在当前项目中使用两种Liquibase配置。我想用于DDL更改的默认配置,第二个用于自定义插入,其中changelog将在另一个位置。
如果我配置SpringLiquibase
,由于@ConditionalOnClass(SpringLiquibase.class)
类中的LiquibaseAutoConfiguration
注释,将跳过默认的自动配置。
如何使用默认自动配置+我的自定义?我可以以某种方式覆盖@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;
}
}
答案 0 :(得分:4)
如果您想使用Spring Boot自动配置的Liquibase功能,那么您的上下文中只能有一个SpringLiquibase
bean。
这是因为@ConditionalOnMissingBean(SpringLiquibase.class)
类中的LiquibaseAutoConfiguration
注释。 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实例使用Liquibase
代替SpringLiquibase
使用一个自动配置SpringLiquibase
和一个纯Liquibase
配置而不是SpringLiquibase
(您需要手动运行迁移并处理SpringLiquibase
中实现的其他内容)
3)仅使用一个SpringLiquibase实例
使用Liquibase的changelogParameters
include
),SpringLiquibase
标记(http://www.liquibase.org/documentation/changelog_parameters.html)和只有一个@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;
}
}
实例的组合。
示例实施:
Liquibase bean配置
<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.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"/>
<include relativeToChangelogFile="false" file="${liquibaseDataChangelogPath}"/>
</databaseChangeLog>
changelog-with-external-data.xml(liquibase.extended-change-log)
1 #include<string.h>
2 #include<stdio.h>
3 #define print(x,c) while(x>0)\
4 {\
5 puts(c);\
6 printf("\n");\
7 --x;\
8 }
9
10 int main()
11 {
12 char c[20];
13 strcpy(c,"Hallelujah");
14 print(5,c);
15 }
请记住,单独更改日志可能会很危险。您必须确保您的更改日志是独立的:
包含的更改日志按照找到的顺序运行,因此需要小心 需要采取措施以确保包含的更改日志 完全独立,或者首先运行任何所需的更改日志。