0

そのための適切な解決策を見つけるのに苦労しています:

同じ構造でデータが異なる複数のデータベースがあります。また、Web アプリがクエリを実行するときは、このクエリをデータベースごとに分離して非同期で実行し、すべてのデータベースから結果を集計して単一の結果として返す必要があります。さらに、クエリが実行されるデータベースのリストを渡すことができるようにしたいと考えています。また、クエリ実行の最大有効期限を渡したいと考えています。また、結果には、超過実行時間など、各データベースのメタ情報が含まれている必要があります。

リレーショナル データベースではなく、特定の API を使用したリモート Web サービスなどの別のデータ ソースを使用できると便利です。

私はSpring/Grailを使用しており、Javaソリューションが必要ですが、アドバイスをいただければ幸いです。

UPD: 準備された解決策、おそらくフレームワークなどを見つけたいです。

4

1 に答える 1

2

これは基本的な OO です。達成しようとしているもの (データの読み込み) を、達成するために使用しているメカニズム (データベース クエリまたは Web サービス呼び出し) から抽象化する必要があります。

このような設計には、通常、実行できることのコントラクトを定義するインターフェイスと、実装に従ってそれを実現する複数の実装クラスが含まれます。

たとえば、次のようなインターフェイスになります。

public interface DataLoader
{
    public Collection<Data> loadData() throws DataLoaderException;
}

次にJdbcDataLoaderWebServiceDataLoader、 などの実装があります。あなたの場合、 の 1 つ以上のインスタンスを指定して実行しDataLoader、結果を合計して集計する別のタイプの実装が必要になります。この実装は次のようになります。

public class AggregatingDataLoader implements DataLoader
{
  private Collection<DataLoader> dataLoaders;
  private ExecutorService executorService;

  public AggregatingDataLoader(ExecutorService executorService, Collection<DataLoader> dataLoaders)
  {
    this.executorService = executorService;
    this.dataLoaders = dataLoaders;
  }

  public Collection<Data> loadData() throws DataLoaderException
  {
    Collection<DataLoaderCallable>> dataLoaderCallables = new ArrayList<DataLoaderCallable>>();

    for (DataLoader dataLoader : dataLoaders)
    {
      dataLoaderCallables.add(new DataLoaderCallable(dataLoader));  
    } 

    List<Future<Collection<Data>>> futures = executorService.invokeAll(dataLoaderCallables);

    Collection<Data> data = new ArrayList<Data>(); 
    for (Future<Collection<Data>> future : futures)
    {
       add.addAll(future.get());
    }      

    return data;
  }

  private class DataLoaderCallable implements Callable<Collection<Data>>
  {
    private DataLoader dataLoader;

    public DataLoaderCallable(DataLoader dataLoader)
    {
      this.dataLoader = dataLoader;  
    }

    public Collection<Data> call()
    {
      return dataLoader.load(); 
    }
  }
}

これにタイムアウトと例外処理ロジックを追加する必要がありますが、要点はわかります。

DataLoaderもう 1 つの重要な点は、テスト中にさまざまな実装を交換したり、モックを使用したりできるように、呼び出しコードでインターフェイスのみを使用する必要があることです。

于 2013-04-26T12:01:00.660 に答える