2016-11-16 346 views
6

使用兩個數據源我使用Spring Boot 1.3.3在我的項目與一個數據庫,現在我想用兩個數據庫與相同的模式不同的連接在春季啓動

我想用相同的存儲庫,實體和尋找方式告訴春天,我要根據不同的情況要使用的數據源。

+0

使用Spring作用輪廓在application.yml –

+0

@Zubair我想在同一時間同時使用,並取決於我的服務的情況選擇一種或另一種。 –

+0

@JeanCedron這是一個複雜的設置。不要回避這個問題,但是你有沒有想過使用消息傳遞層來支持這個問題? Decider App決定要保留哪個數據源。然後它將消息發送到數據源特定的隊列,工作者節點讀取並保存數據。只是一個想法......我已經做了幾雙數據源的應用程序,但他們完全封裝,對於實體,倉庫等分離 –

回答

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(); 
    } 

} 

在Spring啓動應用程序最後注入配置:

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

此外,您還可以在同一時間兩個以上的數據庫。