Java 在spring引导应用程序中使用默认和自定义liquibase配置

Java 在spring引导应用程序中使用默认和自定义liquibase配置,java,spring,spring-boot,liquibase,Java,Spring,Spring Boot,Liquibase,我想在当前项目中使用两种Liquibase配置。我希望用于DDL更改的默认配置和用于自定义插入的第二个配置,其中changelog将位于另一个位置 如果我配置了SpringLiquibase,由于@ConditionalOnClass(SpringLiquibase.class)在LiquibaseAutoConfiguration类中的注释,默认的自动配置将被跳过。 如何使用默认的自动配置+自定义?我可以以某种方式覆盖@ConditionalOnClass注释吗?或者,有没有办法告诉Liqui

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

如果我配置了
SpringLiquibase
,由于
@ConditionalOnClass(SpringLiquibase.class)
LiquibaseAutoConfiguration
类中的注释,默认的自动配置将被跳过。 如何使用默认的自动配置+自定义?我可以以某种方式覆盖@ConditionalOnClass注释吗?或者,有没有办法告诉Liquibase我在应用程序之外有另一个变更日志,并且只有在它存在时才运行它

谢谢

编辑:

@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;
    }
}
<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>
这可能是我问题的解决方案,但是我在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;
    }
}

如果您想使用SpringBoot自动配置的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;
    }
}
<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>

2)对于手动配置的Liquibase实例,使用
Liquibase
而不是
SpringLiquibase

<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>
使用一个自动配置的
SpringLiquibase
和一个纯
Liquibase
配置,而不是
SpringLiquibase
(您需要手动运行迁移并处理在
SpringLiquibase
中实现的其他内容)

3)仅使用一个SpringLiquibase实例

<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>
使用Liquibase的
changelogParameters
(),
include
标记()和一个
SpringLiquibase
实例的组合

实施示例:

@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;
    }
}
<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>
液化豆配置

@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;
    }
}
<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>
@配置
公共类LiquibaseConfiguration{
@自动连线
私有数据源;
//在嵌入式属性文件中定义此属性或使用spring的默认值
@值(${liquibase.change log}”)
私有字符串defaultLiquibaseChangelog;
//在嵌入的属性文件中定义此属性
@值(${liquibase.extended change log}”)
私有字符串扩展的LiquibaSechangeLog;
//可选,在外部配置中或通过命令行参数定义
@值(${liquibase.data change log:#{null}}”)
私有字符串liquibachangelog;
@豆子
公共弹簧液化酶液化酶(){
SpringLiquibase=新的SpringLiquibase();
liquibase.setDataSource(数据源);
if(liquibacheangelog!=null){
//在这里,您可以检查文件是否存在。。。
Map liquibaseChangelogParameters=new HashMap();
liquibaseChangelogParameters.put(“liquibaseExternalDataChangelogPath”,liquibacheangelog);
setChangeLog(扩展的liquibasechangelog);
liquibase.setChangeLogParameters(liquibaseChangelogParameters);
}否则{
setChangeLog(defaultLiquibaseChangelog);
}
//在此处配置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"/>
    <include relativeToChangelogFile="false" file="${liquibaseDataChangelogPath}"/>

</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>

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

包含的更改日志按查找顺序运行,因此care会这样做 需要确保包含的变更日志 完全独立,或者先运行任何必需的变更日志


Include标记对我不起作用,因为可能存在整个变更日志不存在的情况。如果有一个标志failOnMissingFile,它可以帮助我。正如我所说的,一个变更日志位于应用程序内部,其中只有DDL,而另一个变更日志则位于应用程序外部,我想用于数据导入。是的,没错,在这种情况下,它不起作用。如果您的情况取决于环境,那么您可以考虑使用Spring配置文件来加载不同的回溯配置文件(仅包含DDL的一个和其他包含DDL和外部数据的文件)检查我的扩展答案,希望它有帮助。