Java JDBC-连接多个数据库

Java JDBC-连接多个数据库,java,database,jdbc,Java,Database,Jdbc,我正在开发一个需要连接N个数据库系统的应用程序[N个范围,任何地方介于1到350之间] 这个想法是——用户将看到一个数据库列表,并被要求从列表中选择任何或所有数据库 一旦选择了数据库,我需要连接到每个数据库并执行一个存储过程 我计划使用普通的旧JDBC,一次为每个JDBC获取一个连接(或者通过在多个线程中运行它们),执行存储过程并关闭连接 所有这些都应该发生在交易中。最好的方法是什么 如果不是JDBC…还有其他有效的方法吗 更新- 存储过程实际上涉及到运行一些sql—例如更新列、为用户授予权限等

我正在开发一个需要连接N个数据库系统的应用程序[N个范围,任何地方介于1到350之间]

这个想法是——用户将看到一个数据库列表,并被要求从列表中选择任何或所有数据库

一旦选择了数据库,我需要连接到每个数据库并执行一个存储过程

我计划使用普通的旧JDBC,一次为每个JDBC获取一个连接(或者通过在多个线程中运行它们),执行存储过程并关闭连接

所有这些都应该发生在交易中。最好的方法是什么

如果不是JDBC…还有其他有效的方法吗

更新-


存储过程实际上涉及到运行一些sql—例如更新列、为用户授予权限等。

我将创建一个线程池,其中线程数量合理,可能在10到20个线程之间,并将单独的DB connecting和SP executing任务作为using调用。您希望使用threadcount和profile,这毕竟会产生最好的性能

每个
Callable
实现都应将连接详细信息和SP名称作为构造函数参数,以便您可以对不同的DB调用重用相同的实现



更新:好的,这是一个Web应用程序。你不想浪费线程。如果线程池应该由单个并发用户使用,那么您应该真正确保线程池在请求结束时或会话的最高结束时正确运行。但是如果它应该由多个并发用户使用,那么您希望在应用程序范围内共享线程池。在这里,您还需要确保当webapp关闭时它正确关闭。
ServletContextListener
在这里很有用。

这听起来很混乱,但这是你的问题

每个数据库需要一个连接池。我不建议您自己尝试处理连接生命周期。让应用程序服务器为您执行此操作

如果您希望一组数据库参与一个大型事务,那么必须为所有数据库使用JDBCXA驱动程序。您还需要一个JTA事务管理器为您监督事务

存储过程不能包含任何处理事务的逻辑;你必须让JTA来做


您不能说存储过程在做什么。如果它不需要返回任何内容,另一种设计可能是JMS、队列和侦听器池。如果我是你,我会担心穿线。如果我可以的话,我会找到一种方法让容器为我做那些复杂的事情。

正如duffymo在他的评论中指出的那样,如果你有一个事务协调器和两阶段提交,你将只能跨多个数据库做事务

为此,您需要一个处理JTA的J2EE堆栈。如果您在Tomcat或其他没有JTA的容器中运行,有几个选项可以下载和安装


当然,您需要让容器而不是数据库/存储过程来处理事务提交和回滚。

如果您可以使用两个连接,请使用连接池来管理它们。要连接两个数据库,我声明:

public Connection connection1;
public Connection connection2;
DataSource dataSource1;
DataSource dataSource2;
然后是两种类似的方法:

public Connection dbConnect1() throws SQLException {
    ComboPooledDataSource cpds = new ComboPooledDataSource();
    try {
        cpds.setDriverClass("com.mysql.jdbc.Driver");
    } catch (PropertyVetoException e) {
    }
    cpds.setJdbcUrl("jdbc:mysql://localhost:3306/myDatabase1?autoReconnect=true"); 
    cpds.setUser("myMYSQLServerLogin");
    cpds.setPassword("myMYSQLServerPassword");
    cpds.setMinPoolSize(5);
    cpds.setAcquireIncrement(5);
    cpds.setMaxPoolSize(20);
    cpds.setMaxIdleTime(60);
    cpds.setMaxStatements(100);
    cpds.setPreferredTestQuery("SELECT 1");
    cpds.setIdleConnectionTestPeriod(60);
    dataSource1 = cpds;
    connection1 = dataSource1.getConnection();
    return connection1;
}

public Connection dbConnect2() throws SQLException {
    ComboPooledDataSource cpds = new ComboPooledDataSource();
    try {
        cpds.setDriverClass("com.mysql.jdbc.Driver");
    } catch (PropertyVetoException e) {
    }
    cpds.setJdbcUrl("jdbc:mysql://localhost:3306/myDatabase2?autoReconnect=true"); 
    cpds.setUser("myMYSQLServerLogin");
    cpds.setPassword("myMYSQLServerPassword");
    cpds.setMinPoolSize(5);
    cpds.setAcquireIncrement(5);
    cpds.setMaxPoolSize(20);
    cpds.setMaxIdleTime(60);
    cpds.setMaxStatements(100);
    cpds.setPreferredTestQuery("SELECT 1");
    cpds.setIdleConnectionTestPeriod(60);
    dataSource2 = cpds;
    connection2 = dataSource2.getConnection();
    return connection2;
}

什么样的申请?桌面还是web?这是一个web应用程序。我的理解是,您不需要在单个事务中执行此操作,这是真的吗?还有更多的需要考虑。我计划在一次交易中完成这项工作…不确定复杂性!我猜所有的数据库连接URL都保存在一个中央数据库中。我相信我们不想在应用服务器中创建数据源[如前所述,我有大约1-350个数据源]……在这种情况下,我想我需要自己处理连接生命周期,对吗?只需在一个周期内为350个数据库创建连接。如果需要清理代码,请从主数据库中提取每个数据库的参数。在应答中编写代码是很好的,但是编写解释此代码为何工作会更好
public static Connection getconnection(String db,String host){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://"+**Pass Your Host Here 
Like Localhost**+"/"+Pass Your DB Name** +"?useUnicode=yes&characterEncoding=UTF- 
8","root","root");
return con;
} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} 
}