2016-11-16 14 views
6

Używam Spring Boot 1.3.3 w moim projekcie z jeden bazie danych, teraz chcę użyć dwóch baz danych z samego schematu ale różnych połączeń.Korzystanie z dwóch źródeł danych w Spring Boot

Chcę użyć tych samych repozytoriów, encji i znaleźć sposób, aby poinformować wiosnę, którego źródła danych chcę używać w zależności od sytuacji.

+0

Użyj aktywnych profili Spring w application.yml –

+0

@Zubair Chcę używać obu jednocześnie iw zależności od sytuacji w mojej usłudze, wybierz jedną lub drugą. –

+0

@JeanCedron To skomplikowana konfiguracja. Aby nie uchylać się od pytania, ale czy myślałeś o użyciu warstwy wiadomości, aby to ułatwić? Decider App podejmuje decyzję, do którego źródła danych się należy. Następnie wysyła wiadomość do kolejki specyficznej dla źródła danych, dla której węzeł roboczy odczytuje i utrwala dane. Tylko jedna myśl ... Zrobiłem kilka podwójnych aplikacji źródła danych, ale były one w pełni oddzielone pakietami pod względem encji, repozytoriów itp. –

Odpowiedz

5

Jeśli ktoś ma ten problem, znalazłem rozwiązanie:

First twoi application.properties powinna wyglądać następująco:

datasource: 
primary: 
    url: jdbc:mysql://localhost:3306/primary_db 
    username: your_username 
    password: your_password 
    driver-class-name: com.mysql.jdbc.Driver 
secondary: 
    url: jdbc:mysql://localhost:3306/secondary_db 
    username: your_username 
    password: your_password 
    driver-class-name: com.mysql.jdbc.Driver 

Po tym, trzeba utworzyć enum z baz danych:

public enum Database { 
    PRIMARY, 
    SECONDARY 
} 

Następnie należy utworzyć ThreadLocal:

public class DatabaseThreadContext { 

    private static final ThreadLocal<Database> current = new ThreadLocal<>(); 

    public static void setCurrentDatabase(Database database) { 
     current.set(database); 
    } 

    public static Object getCurrentDatabase() { 
     return current.get(); 
    } 

} 

Nadchodzi magiczny, trzeba użyć AbstractRoutingDataSource który został wdrożony na wiosnę 2 z powrotem w 2007 roku:

public class RoutingDataSource extends AbstractRoutingDataSource { 

    @Override 
    protected Object determineCurrentLookupKey() { 
     return DatabaseThreadContext.getCurrentDatabase(); 
    } 

} 

Wreszcie wstrzyknąć konfigurację w swoim wiosennym Boot app:

@Configuration 
public class DatabaseRouter { 

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

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

    @Bean 
    @Primary 
    public DataSource dataSource() { 
     Map<Object, Object> targetDatasources = new HashMap<Object, Object>(){{ 
      put(Database.SECONDARY, secondaryDataSource()); 
      put(Database.PRIMARY, primaryDataSource()); 
     }}; 
     RoutingDataSource routingDataSource = new RoutingDataSource(); 
     routingDataSource.setDefaultTargetDataSource(primaryDataSource()); 
     routingDataSource.setTargetDataSources(targetDatasources); 
     routingDataSource.afterPropertiesSet(); 
     return routingDataSource; 
    } 

} 

W każdym żądaniu, jeśli chcesz zmienić bazę danych, skorzystaj z tej funkcji: DatabaseThreadContext.setCurrentDatabase(Database.PRIMARY);.

Ponadto można mieć więcej niż dwie bazy danych w tym samym czasie.