2016-09-29 8 views
0

私の新しいプロジェクトでは、クライアントのリクエストでデータを返すための基本的な残りのAPIを作成しました。ただし、クライアントは、HTTP GET要求のパラメータとして、自分の選択したデータベースを選択する必要があります。(Spring-boot&Spring data jpa)その場でデータソースを変更するには?

私の質問は、私がSprint-bootでそれを行う方法を知らないということです。私は多くの異なるデータソースを提供できることを知っていますが、要求を検査した後、希望するデータソースをどのように変更できますか?ここで

はうまく機能し、私のデータソースの設定、次のとおりです。

@Configuration 
public class DataSourceConfig { 

    @Bean 
    @Primary 
    @ConfigurationProperties(prefix="datasource.dev21") 
    public DataSource dev21DataSource() throws SQLException { 
     return DataSourceBuilder.create().build(); 
    } 

    @Bean 
    @ConfigurationProperties(prefix="datasource.dev22") 
    public DataSource dev22DataSource() throws SQLException { 
     return DataSourceBuilder.create().build(); 
    } 
} 

私は動的にdev21とdev22を切り替えたい場合は、私が何をすべき? 私はクラスに関する記事を読んでいますAbstractRoutingDataSource、しかし私はそれを使用する方法がわかりません。それをテストしなくても、

+0

では、こちらをご覧ください:[ダイナミックデータベース接続の切り替えとデータベースのルーティングによるアプリケーションのマルチテナンシー](http://springrules.blogspot.com/2017/08/dynamic-database-co nnection-switching.html) – vRaptor

答えて

0

、そして唯一のjavadocを通じて簡単に見て、このようなものは、クラスから他の動作が必要な場合はoverride他の方法をお勧めします

@Configuration 
public class DataSourceConfig { 

    public DataSource dev21DataSource() throws SQLException { 
     return DataSourceBuilder.create().build(); 
    } 

    public DataSource dev22DataSource() throws SQLException { 
     return DataSourceBuilder.create().build(); 
    } 

    @Bean 
    public DataSource dataSource() throws SQLException { 
     RoutingDataSource ds = new RoutingDataSource(); 

     DataSource ds21 = dev21DataSource(); 
     DataSource ds22 = dev22DataSource(); 

     Map dataSources = new HashMap(); 
     dataSources.put(1, ds21); 
     dataSources.put(2, ds22); 

     ds.setDefaultTargetDataSource(ds21); 
     ds.setTargetDataSources(dataSources); 

     return ds; 
    } 
} 

public class RoutingDataSource extends AbstractRoutingDataSource { 

    @Override 
    protected Object determineCurrentLookupKey() { 
     if (true) { //Should probably be some thread/tracaction/request safe check 
      return 1; 
     } else { 
      return 2; 
     } 
    } 
} 

を働くかもしれません。

// create class to hold the "key" to choose your datasource 
// you will determine it from your GET or POST request 
// It uses ThreadLocal so you will get one per each request 
public class SomeRequestContext { 
    private static ThreadLocal<Object> keyToChoseDataSource = new ThreadLocal<>(); 
    public static void setKeyToChoseDataSource(Object key) { 
     keyToChoseDataSource.set(key); 
    } 
    public static Object getKeyToChoseDataSource() { 
     return keyToChoseDataSource.get(); 
    } 
} 

// This is you AbstractRoutingDataSource implementation that will 
// get the key out of the context class above 
public class MultiDataSource extends AbstractRoutingDataSource { 
    @Override 
    protected Object determineCurrentLookupKey() { 
     return SomeRequestContext.getKeyToChoseDataSource(); 
    } 
} 

そして、あなたの構成内:それは、この線に沿って行くべき

0

// Here you just put all your data sources into the AbstractRoutingDataSource implementation 
    @Bean 
    @Primary 
    public DataSource dataSource() { 
     MultiDataSource dataSource = new MultiDataSource(); 
     dataSource.setDefaultTargetDataSource(someDefaultDataSource()); 
     Map<Object,DataSource> resolvedDataSources = new HashMap<Object,DataSource>(); 
     resolvedDataSources.put("dev21",buildDataSource21()); 
     resolvedDataSources.put("dev22",buildDataSource22()); 
     // ...etc... 
     dataSource.setTargetDataSources(resolvedDataSources); 
     dataSource.afterPropertiesSet(); 
     return dataSource; 
    } 

そして、あなたのコントローラ

@Controller 
public class YourController { 
    @Autowired 
    private YourRepository yourRepository; 
    @RequestMapping(path = "/path", method= RequestMethod.POST) 
    public ResponseEntity<?> createStuff() { 
     TenantContext.setCurrentTenant(tenantName); 
     SomeRequestContext.setKeyToChoseDataSource(getKeyFromRequest()); // this will be dev21 or dev22 or whatever 

     SomeStuff stuff = new SomeStuff(); 
     yourRepository.save(stuff); // will be saved to the correct database 
     return ResponseEntity.ok(stuff); 
    } 
} 
関連する問題