2011-02-08 1 views
2

顧客ごとにを動的に使用するとします。顧客がサービスに加入したときにデータベースを作成します。すべてのデータベースは同じスキーマに基づいています。SpringとHibernateを介して複数の動的に作成されたデータベースを管理するベストプラクティスは何ですか?

顧客が認証されると(顧客の詳細すべてを管理する1つのマスターデータベース)、固有のユーザ名が、対応するデータベースにアクセスして必要な情報を取得するために使用されます。

質問1:上記の問題は、この種の問題に対する優れたアプローチと考えることができますか?それとも良い解決策がありますか?

質問2::良い解決策がない場合は、Spring & Hibernateを使用してどのように実装できますか?

編集:私が知る必要があるのは、Spring構成ファイルを編集せずに顧客サブスクリプションでデータソース作成を実装する方法です。それは自動化する必要があります。

+0

あなたは実際に動的に作成されたdbsを作成して使用しましたか? – Lipis

答えて

6

質問1:さまざまなオプションがあります。 This article talksこれらのオプションについては、それぞれのオプションの賛否両論があります。

質問2:

  1. 春はdynamic data source routingをサポートしています。そこから始めるべきかもしれない。
  2. データソースを動的に作成することもできます。は、Springのデータソースを管理する場合にとなります。実行中のSpringアプリケーションctxにタイプcom.mchange.v2.c3p0.ComboPooledDataSourceまたはorg.apache.commons.dbcp.BasicDataSourceのBeanを登録するだけです。これを行うにはAltering your applicationContext at runtimeの記事を読んでください。
関連

  1. Configure spring datasource for hibernate and @Transactional
  2. DBCP
  3. c3p0
+0

いただきありがとうございます。春のサンプルがどのように役立つのか見当たりませんでした。各サービスのBeanは、XMLの中で_ハードコードされています。他の顧客が_力学的に追加されている場合は、XMLを変更する必要があります。顧客が動的に追加されるケース(事前定義されたものだけでなく)を処理する方法を知りたい。 –

+0

@Adnan Doric - あなたがそこからスタートし、必要に応じて提供された実装をカスタマイズする必要があると述べた理由は、 –

+0

です。その実装を開始する方法がわからないので、まず質問をしました。私は、実行時に**スワップされたデータソースの実装をたくさん見ることができますが、ランタイム**データソースで動的に作成されたデータソース**は何もありません。 –

2

私はかなりの時間のために、この問題に苦労し、私はそれをハックするために管理!そのため、クライアント用の新しいDBが追加された場合、各クライアントは専用のDBを持ち、スキーマ設計は同じであるため、データベースはソフトウェアを介して即座にアクセスできます。

データソースは、必要なDBに接続するために実行時に変更されます。典型的には、我々の規約は、ユーザのアカウント名はDb名である。

のApplicationContext:ここ

https://serverurl/accountnameが内訳です。XML TenantRouterクラスで

<bean id="dataSource" class="com.package.util.TenantRouter"> 
    <property name="targetDataSources"> 
     <map> 
      <entry key="db" value-ref="db"/> 
     </map> 
    </property> 
    <property name="defaultTargetDataSource" ref="parentDataSource"/> 
</bean> 

<bean id="parentDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="org.postgresql.Driver"/> 
    <property name="url" value="jdbc:postgresql://localhost:6432/db?autoReconnect=true"/> 
    <property name="username" value="DBUSER"/> 
    <property name="password" value="DBPASS"/> 
</bean> 

<bean id="db" parent="parentDataSource"> 
    <property name="url" value="jdbc:postgresql://localhost:5432/db?autoReconnect=true"/> 
    <property name="username" value="DBUSER"/> 
    <property name="password" value="DBPASS"/> 
</bean> 

、これらの2つの方法が不可欠です:

@Override 
protected Object determineCurrentLookupKey() { 
    String tenant="defaultdb"; 
    if (UserContextUtil.getUserContext()!=null){ 
     tenant = UserContextUtil.getUserContext().getTenant().toString(); 
    } 
    return tenant; 
} 

@Override 
protected DataSource determineTargetDataSource() { 
    //current DB 
    String db_name = (String) determineCurrentLookupKey(); 
    //System.out.println("THIS DB:"+db_name); 
    DriverManagerDataSource ds = new DriverManagerDataSource(); 
    ds.setDriverClassName("org.postgresql.Driver"); 

    String url="jdbc:postgresql://localhost:5432/"+db_name+"?autoReconnect=true"; 
    //System.out.println("URL:"+url); 
    ds.setUrl(url); 
    ds.setUsername(username); 
    ds.setPassword(password); 
    return ds; 
} 

UserContextUtil.getUserContext().getTenant().toString()は、クライアントのURLで提供されるためにどの接続するために要求さDbとを返します。

私はこれがこのような頭痛を経験する人に役立つことを願っています。

乾杯!

関連する問題