2016-11-16 197 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);

此外,您还可以在同一时间两个以上的数据库。