Java连接到多个数据库

问题描述:

我正在创建一个连接到多个数据库的java应用程序。用户将能够从下拉框中选择他们想要连接的数据库。Java连接到多个数据库

程序然后通过将名称传递给创建初始上下文的方法来连接到数据库,以便它可以与Oracle Web逻辑数据源进行通信。

public class dbMainConnection { 

    private static dbMainConnection conn = null; 
    private static java.sql.Connection dbConn = null; 
    private static javax.sql.DataSource ds = null; 
    private static Logger log = LoggerUtil.getLogger(); 

    private dbMainConnection(String database) { 

     try { 

      Context ctx = new InitialContext(); 

      if (ctx == null) { 
       log.info("JDNI Problem, cannot get InitialContext"); 
      } 

       database = "jdbc/" + database; 
       log.info("This is the database string in DBMainConnection" + database); 
       ds = (javax.sql.DataSource) ctx.lookup (database); 


     } catch (Exception ex) { 
      log.error("eMTSLogin: Error in dbMainConnection while connecting to the database : " + database, ex); 
     } 

    } 

    public Connection getConnection() { 

     try { 

      return ds.getConnection(); 

     } catch (Exception ex) { 
      log.error("Error in main getConnection while connecting to the database : ", ex); 
      return null; 
     } 

    } 

    public static dbMainConnection getInstance(String database) { 

     if (dbConn == null) { 
      conn = new dbMainConnection(database); 
     } 

     return conn; 

    } 

    public void freeConnection(Connection c) { 
     try { 
      c.close(); 
      log.info(c + " is now closed"); 
     } catch (SQLException sqle) { 
      log.error("Error in main freeConnection : ", sqle); 
     } 
    } 

} 

我的问题是如果有人忘记为数据库创建数据源但是仍将其添加到下拉框中会发生什么?现在发生的情况是,如果我尝试连接到没有数据源的数据库,那么它会报错,无法获得连接。这是我想要的,但如果我连接到一个数据库,它首先有一个数据源,它可以工作,然后尝试连接到没有数据源的数据库,它又出错

javax .naming.NameNotFoundException:无法解析'jdbc.peterson'。解决'jdbc';剩余的名字'彼得森'。

再次我希望,但什么是混淆我是它,然后抓住最后一次正确的连接,也就是针对不同的数据库,并处理一切,仿佛什么都没有发生。

任何人都知道这是为什么?是weblogic缓存连接还是作为失败安全的东西?以这种方式建立联系是不是一个好主意?

+0

您是否尝试将dbMainConnection的捕获范围中的ds值清空? –

您正在将类中的唯一数据源(和连接以及dbMainConnection)存储在静态变量中。每次有人要求数据源时,都要用新数据源替换前一个数据源。如果从JNDI获取数据源时发生异常,则静态数据源将保持原样。你不应该在静态变量中存储任何东西。由于您的dbMainConnection类是使用数据库的名称构建的,并且有多个数据库名称,因此将其设置为单例是没有意义的。

只需使用下面的代码来访问数据源:

public final class DataSourceUtil { 
    /** 
    * Private constructor to prevent unnecessary instantiations 
    */ 
    private DataSourceUtil() { 
    } 

    public static DataSource getDataSource(String name) { 
     try { 
      Context ctx = new InitialContext(); 
      String database = "jdbc/" + name; 
      return (javax.sql.DataSource) ctx.lookup (database); 
     } 
     catch (NamingException e) { 
      throw new IllegalStateException("Error accessing JNDI and getting the database named " + name); 
     } 
    } 
} 

而让来电者获得从数据源的连接并关闭它,当他们使用完。

+0

太棒了。谢谢您的帮助。很明显,我是一个java newb,所以非常感谢你的明确解释和代码。只是为了确保我明白。我摆脱了dbconnect类,而是使用dataSourceUtil类来获取数据源。然后用它创建我对不同数据库的连接。 Afterwords关闭数据库连接和初始上下文。是对的吗? – enderjs

+0

正确(除了InitialContext关闭,您无法关闭,但我认为它不会打开它)。 –

查找不存在的数据源时,您正在捕获JNDI异常,但您的单例仍然保留对之前查找的数据源的引用。作为A.B.凯德说,除了特例之外,甚至在此之前,对空白的参照都是空的。

在更一般的说明中,也许使用Singleton并不是最好的主意。