2016-08-18 3 views
2

Я бы хотел использовать две конфигурации Liquibase в текущем проекте. Конфигурация по умолчанию, которую я хотел бы использовать для DDL-изменений, и вторую для пользовательских вставок, где changelog будет в другом месте.Используйте настройки по умолчанию и пользовательские конфигурации Liquibase в приложении весенней загрузки

Если я настрою SpringLiquibase, автоконфигурация по умолчанию будет пропущена из-за @ConditionalOnClass(SpringLiquibase.class) аннотации в классе LiquibaseAutoConfiguration. Как использовать автоконфигурацию по умолчанию + мой пользовательский? Можно ли каким-либо образом переписать аннотацию @ConditionalOnClass? Или, может быть, есть способ сказать Liquibase, что у меня есть другой журнал изменений вне приложения и запускать его, только если он присутствует?

Благодаря

редактировать:

Это может быть решение моей проблемы, но у меня есть проблема с загрузкой внешних файлов (файлы за пределами CLASSPATH), в 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; 
    } 
} 

ответ

2

Если вы хотите использовать Spring бутс автоконфигурацию функции LiquiBase, то вы можете иметь только один SpringLiquibase боба в вашем контексте. Это из-за @ConditionalOnMissingBean(SpringLiquibase.class) аннотация в LiquibaseAutoConfiguration класс. Условная функция Spring ищет экземпляры SpringLiquibase и экземпляры подкласса, поэтому расширение класса SpringLiquibase не устранит эту проблему.

Невозможно переопределить LiquibaseAutoConfiguration. В этом случае у вас есть 3 решения, которые могли бы решить вашу проблему:

1) выполнить два отдельных 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; 
    } 
} 

и

@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 для случая с жидкостной жидкостью с ручной настройкой

Используйте один автоконфигурацию SpringLiquibase и одну чистой Liquibase конфигурации вместо SpringLiquibase (Вам нужно будет вручную запускать миграции и обрабатывать другие вещи, которые реализуются в SpringLiquibase)

3) Используйте только один экземпляр SpringLiquibase

Использовать комбинацию Liquibase's changelogParameters (http://www.liquibase.org/documentation/changelog_parameters.html), include тег (http://www.liquibase.org/documentation/include.html) и только один экземпляр SpringLiquibase.

Пример реализации:

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; 

    //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.журнал изменений)

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

изменений-с-внешнего-data.xml (liquibase.extended-изменений)

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

запомнить, что наличие отдельных списков изменений может быть опасным. Вы должны убедиться, что ваши независимые списком изменений:

Включено списком изменений выполняются в порядке, они находятся так служивание необходимо предпринять, чтобы убедиться, что включены либо списком изменений полностью независимы, или что все необходимые изменения списков выполняются первыми.

+0

Включить тег не работает для меня, потому что может быть ситуация, когда весь журнал изменений не существует. Если бы был флаг failOnMissingFile, это могло бы помочь мне. Один журнал изменений, как я сказал, находится внутри приложения, в которое будут отправлены только DDL, а другой журнал изменений, который я хочу использовать для импорта данных, будет находиться вне приложения. – bilak

+0

Да, в этом случае он не будет работать. Если ваша ситуация зависит от среды, вы можете рассмотреть использование профилей пружин для загрузки различных конфигурационных файлов журнала (один с включенным только DDL и другим с включенными как DDL, так и внешними данными) –

+0

Проверьте мой расширенный ответ, надейтесь, что это поможет –

 Смежные вопросы

  • Нет связанных вопросов^_^