2016-11-16 5 views
6

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

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

+0

Используйте активные профили пружины в application.yml –

+0

@ Zubair Я хочу использовать оба одновременно, и в зависимости от ситуации в моей службе выберите тот или иной. –

+0

@JeanCedron Это сложная настройка. Не уклониться от вопроса, но подумали ли вы об использовании слоя обмена сообщениями для его устранения? Приложение Decider принимает решение о том, какой ресурс данных должен сохраняться. Затем он отправляет сообщение в конкретную очередь данных, для которой рабочий узел считывает и сохраняет данные. Просто мысль ... Я сделал несколько приложений с двумя источниками данных, но они были полностью разделены на пакеты по отношению к объектам, репозиториям и т. Д. –

ответ

5

Если кто имеет эту проблему, я нашел решение:

Первого вашего application.properties должен выглядеть следующим образом:

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 

После этого, вы должны создать перечисление с баз данных:

public enum Database { 
    PRIMARY, 
    SECONDARY 
} 

Затем вы создаете 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(); 
    } 

} 

Здесь приходит магия, вы должны использовать AbstractRoutingDataSource, который был реализован весной 2 еще в 2007 году:

public class RoutingDataSource extends AbstractRoutingDataSource { 

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

} 

Наконец впрыснуть конфигурации в Спринг загрузки приложения:

@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; 
    } 

} 

В каждом запросе, если вы хотите изменить между вашими базами данных, вы просто используете эту функцию: DatabaseThreadContext.setCurrentDatabase(Database.PRIMARY);.

Кроме того, вы можете иметь более двух баз данных одновременно.