2

顧客がサービスにサブスクライブするときに、顧客ごとにデータベースを動的に作成する必要があるとします。すべてのデータベースは同じスキーマに基づいています。

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

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

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

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

4

2 に答える 2

6

質問 1:さまざまなオプションがあります。この記事では、これらのオプションについて、各オプションの長所と短所について説明します。

質問2:

  1. Spring は動的データ ソース ルーティングをサポートします。そこから始めるべきかもしれません。
  2. Spring にデータ ソースを管理させる場合は、データ ソースを動的に作成することもできます。必要な作業は、実行中の Spring アプリ ctx にcom.mchange.v2.c3p0.ComboPooledDataSourceまたはorg.apache.commons.dbcp.BasicDataSourceタイプの Bean を登録することだけです。これを行う方法については、記事Altering your applicationContext at runtimeを参照してください。

関連している

  1. hibernate および @Transactional の Spring データソースを構成する
  2. DBCP
  3. c3p0
于 2011-02-08T04:04:51.557 に答える
3

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

データ ソースは、必要な DB に接続するために実行時に変更されます。通常、私たちの慣習は、ユーザーのアカウント名がデータベース名である、例えばhttps://serverurl/accountname です

内訳は次のとおりです。

Applicationcontext.xml

<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>

TenantRouter クラスでは、次の 2 つのメソッドは IMPERATIVE です。

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

は、クライアントの URL で指定された接続先のUserContextUtil.getUserContext().getTenant().toString()要求された Db を返します。

そんな頭痛に悩まされている方の参考になれば幸いです。

乾杯!

于 2015-02-11T17:04:18.270 に答える