gpt4 book ai didi

java - 在 spring boot 应用程序中使用默认和自定义 liquibase 配置

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:05:19 25 4
gpt4 key购买 nike

我想在当前项目中使用 Liquibase 的两种配置。我想将默认配置用于 DDL 更改,第二个配置用于自定义插入,其中更改日志将位于另一个位置。

如果我配置 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。这是因为 @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 而不是 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>

请记住,拥有单独的变更日志可能很危险。您必须确保您的变更日志是独立的:

Included change-logs are run in the order they are found so care does need to be taken to make sure that the included changelogs are either completely independent, or that any required changelogs are run first.

关于java - 在 spring boot 应用程序中使用默认和自定义 liquibase 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39014463/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com