programing

여러 데이터 소스를 위해 봄에 액체 기반을 설정하는 방법은 무엇입니까?

telecom 2023. 6. 24. 08:47
반응형

여러 데이터 소스를 위해 봄에 액체 기반을 설정하는 방법은 무엇입니까?

설정해야 합니다.liquibase2인분datasourcesSpring현재로서는 오직 한 사람만이liquibase설정이 가능하며 데이터 원본을 선택할 수 있습니다.

스프링 부트를 사용하는 경우 다음과 같은 설정을 사용할 수 있습니다.

구성 클래스:

@Configuration
public class DatasourceConfig {

    @Primary
    @Bean
    @ConfigurationProperties(prefix = "datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "datasource.primary.liquibase")
    public LiquibaseProperties primaryLiquibaseProperties() {
        return new LiquibaseProperties();
    }

    @Bean
    public SpringLiquibase primaryLiquibase() {
        return springLiquibase(primaryDataSource(), primaryLiquibaseProperties());
    }

    @Bean
    @ConfigurationProperties(prefix = "datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "datasource.secondary.liquibase")
    public LiquibaseProperties secondaryLiquibaseProperties() {
        return new LiquibaseProperties();
    }

    @Bean
    public SpringLiquibase secondaryLiquibase() {
        return springLiquibase(secondaryDataSource(), secondaryLiquibaseProperties());
    }

    private static SpringLiquibase springLiquibase(DataSource dataSource, LiquibaseProperties properties) {
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setDataSource(dataSource);
        liquibase.setChangeLog(properties.getChangeLog());
        liquibase.setContexts(properties.getContexts());
        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;
    }


...

}

속성.yml

datasource:
  primary:
    url: jdbc:mysql://localhost/primary
    username: username
    password: password
    liquibase:
      change-log: classpath:/db/changelog/db.primary.changelog-master.xml
  secondary:
    url: jdbc:mysql://localhost/secondary
    username: username
    password: password
    liquibase:
      change-log: classpath:/db/changelog/db.secondary.changelog-master.xml

특정 changeSet로 여러 dataSources를 만들 수 있는 프로젝트를 수행했습니다. 따라서 다른 dataSource를 추가해야 할 경우 application.yml만 변경하면 되므로 더 이상 코드를 변경할 필요가 없습니다.

구성 클래스

@Configuration
@ConditionalOnProperty(prefix = "spring.liquibase", name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties(LiquibaseProperties.class)
@AllArgsConstructor
public class LiquibaseConfiguration {

    private LiquibaseProperties properties;
    private DataSourceProperties dataSourceProperties;

    @Bean
    @DependsOn("tenantRoutingDataSource")
    public MultiTenantDataSourceSpringLiquibase liquibaseMultiTenancy(Map<Object, Object> dataSources,
                                                                      @Qualifier("taskExecutor") TaskExecutor taskExecutor) {
        // to run changeSets of the liquibase asynchronous
        MultiTenantDataSourceSpringLiquibase liquibase = new MultiTenantDataSourceSpringLiquibase(taskExecutor);
        dataSources.forEach((tenant, dataSource) -> liquibase.addDataSource((String) tenant, (DataSource) dataSource));
        dataSourceProperties.getDataSources().forEach(dbProperty -> {
            if (dbProperty.getLiquibase() != null) {
                liquibase.addLiquibaseProperties(dbProperty.getTenantId(), dbProperty.getLiquibase());
            }
        });

        liquibase.setContexts(properties.getContexts());
        liquibase.setChangeLog(properties.getChangeLog());
        liquibase.setDefaultSchema(properties.getDefaultSchema());
        liquibase.setDropFirst(properties.isDropFirst());
        liquibase.setShouldRun(properties.isEnabled());
        return liquibase;
    }

}

application.yml

spring:
  dataSources:
    - tenantId: db1
      url: jdbc:postgresql://localhost:5432/db1
      username: postgres
      password: 123456
      driver-class-name: org.postgresql.Driver
      liquibase:
        enabled: true
        default-schema: public
        change-log: classpath:db/master/changelog/db.changelog-master.yaml
    - tenantId: db2
      url: jdbc:postgresql://localhost:5432/db2
      username: postgres
      password: 123456
      driver-class-name: org.postgresql.Driver
    - tenantId: db3
      url: jdbc:postgresql://localhost:5432/db3
      username: postgres
      password: 123456
      driver-class-name: org.postgresql.Driver

저장소 링크: https://github.com/dijalmasilva/spring-boot-multitenancy-datasource-liquibase

저는 고정된 수의 데이터 소스가 아니라 동적인 양의 데이터 소스를 지원해야 했습니다.나는 당신이 같은 것을 사용할 수 있다는 것을 발견했습니다.SpringLiquibase다음과 같은 서비스를 만들어 여러 데이터 소스용으로 사용할 수 있습니다.

@Service
@DependsOn("liquibase")
public class LiquibaseService {

    @Autowired
    @Qualifier("liquibase")
    private SpringLiquibase liquibase;

    @PostConstruct
    public void initialize() {

        /* Obtain datasources from wherever. I obtain them from a master DB. It's up to you. */
        List<DataSource> dataSources = obtainDataSources();

        for (DataSource dataSource : dataSources) {
            try {
                liquibase.setDataSource(dataSource);
                liquibase.setChangeLog("classpath:liquibase/emp.changelog.xml");
                liquibase.setShouldRun(true);

                // This runs Liquibase
                liquibase.afterPropertiesSet();

            } catch (LiquibaseException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

}

이것이 효과가 있으려면, 당신은 그것을 가져야 합니다.SpringLiquibase어딘가에 신고되어 있습니다이 예에서는 구성 파일 중 하나에서 다음을 얻었습니다.

@Bean
public SpringLiquibase liquibase(LiquibaseProperties properties) {

    SpringLiquibase liquibase = new SpringLiquibase();
    liquibase.setDataSource(systemDataSource);
    liquibase.setChangeLog("classpath:liquibase/sis.changelog.xml");
    liquibase.setContexts(properties.getContexts());
    liquibase.setDefaultSchema(properties.getDefaultSchema());
    liquibase.setDropFirst(properties.isDropFirst());


    liquibase.setLabels(properties.getLabels());
    liquibase.setChangeLogParameters(properties.getParameters());
    liquibase.setRollbackFile(properties.getRollbackFile());

    // This is because we are running the process manually. Don't let SpringLiquibase do it.
    liquibase.setShouldRun(false);

    return liquibase;
}

위의 내용은 데이터 소스 구성 요구 사항에 따라 크게 달라집니다.스프링-리퀴베이스 자동 구성이 시작되지 않도록 기본 애플리케이션 클래스에 이 기능을 추가해야 할 수도 있습니다.

@SpringBootApplication(exclude = {
    LiquibaseAutoConfiguration.class
})
public class Application {

    // Stuff...

}

데이터 소스 2개와 콩 2개만 있으면 됩니다.

<bean id="liquibase1" class="liquibase.integration.spring.SpringLiquibase">
      <property name="dataSource" ref="dataSource1" />
      <property name="changeLog" value="classpath:db1-changelog.xml" />
 </bean>
 <bean id="liquibase2" class="liquibase.integration.spring.SpringLiquibase">
      <property name="dataSource" ref="dataSource2" />
      <property name="changeLog" value="classpath:db2-changelog.xml" />
 </bean>

여러 개의 liquibase 인스턴스를 실행할 수도 있습니다(즉, 1차 및 2차에만 제한되지 않음).

예를 들어, 구성 Java에는 다음이 포함됩니다.

@Bean
@ConfigurationProperties(prefix = "liquibase1")
...
@Bean
@ConfigurationProperties(prefix = "liquibase2")
...
@Bean
@ConfigurationProperties(prefix = "liquibase3")

application.property에는 다음이 있습니다.

liquibase1.default-schema=schemaA
...
liquibase2.default-schema=schemaB
...
liquibase3.default-schema=schemaC
...

그리고 (흥미롭게도) 이러한 springLequibase 인스턴스는 동일한 데이터 소스 또는 다른 데이터 소스를 사용할 수 있습니다.네가 좋든 좋든.

런닝 오더?debug에서 관찰한 결과 모든 liquibase 마이그레이션은 application.properties에 기록한 순서에 따라 실행됩니다.한 데이터 소스에서 마이그레이션을 실행한 다음 다른 데이터 소스로 이동한 다음 이 데이터 소스로 돌아와 다른 작업을 실행하려는 사용자는... 이 다중 liquibase 인스턴스 접근 방식을 시도해 보는 것이 좋습니다.

언급URL : https://stackoverflow.com/questions/43523971/how-to-set-up-liquibase-in-spring-for-multiple-data-sources

반응형