Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 来自不同数据源或数据库的异步多查询_Java_Grails_Asynchronous_Datasource_Multiple Databases - Fatal编程技术网

Java 来自不同数据源或数据库的异步多查询

Java 来自不同数据源或数据库的异步多查询,java,grails,asynchronous,datasource,multiple-databases,Java,Grails,Asynchronous,Datasource,Multiple Databases,我很难找到合适的解决方案: 我有几个结构相同但数据不同的数据库。当我的web应用程序执行一个查询时,它必须将每个数据库的查询分开并异步执行,然后聚合所有数据库的结果并作为单个结果返回。另外,我希望能够传递执行查询的数据库列表,还希望传递执行查询的最长过期时间。此外,结果必须包含每个数据库的元信息,例如多余的执行时间 如果可以使用另一个数据源,比如带有特定API的远程web服务,而不是关系数据库,那就太好了 我使用Spring/Grail,需要java解决方案,但我很乐意听取任何建议 UPD:我想

我很难找到合适的解决方案:

我有几个结构相同但数据不同的数据库。当我的web应用程序执行一个查询时,它必须将每个数据库的查询分开并异步执行,然后聚合所有数据库的结果并作为单个结果返回。另外,我希望能够传递执行查询的数据库列表,还希望传递执行查询的最长过期时间。此外,结果必须包含每个数据库的元信息,例如多余的执行时间

如果可以使用另一个数据源,比如带有特定API的远程web服务,而不是关系数据库,那就太好了

我使用Spring/Grail,需要java解决方案,但我很乐意听取任何建议


UPD:我想找到准备好的解决方案,可能是框架之类的。这是基本的OO。您需要从用于实现数据库查询或web服务调用的机制中抽象出您试图实现的内容(加载数据)

这样的设计通常涉及一个接口,该接口定义了可以做什么的契约,然后是多个实现类,这些实现类根据它们的实现来实现

例如,您将得到一个界面,该界面类似于:

public interface DataLoader
{
    public Collection<Data> loadData() throws DataLoaderException;
}
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
接口,以便您可以在测试期间交换不同的实现或使用mock。

好的,问题是什么?你试过什么?是什么阻止了你这么做?所以,我想找到准备好的解决方案,也许是框架或者类似的东西。但我发现只有一件事是UnityJDBC,但它只适用于关系数据库,并且没有元信息和查询的过期时间。谢谢您的详细回答。我同意,实现起来并不难,但我认为我可以找到类似mapreduce框架(比如hadoop)的东西来解决我的问题。但似乎我必须自己写。做map reduce的工作是知道如何映射要缩减的数据集和reduce本身——这两者都将针对您的问题。类似Hadoop或大多数分布式缓存技术的东西可以实现map reduce,但您仍然可以实现它们的接口来完成实际工作。我的建议是,如果不引入框架(额外的依赖项)就可以轻松完成,那么请保持简单,忽略框架。