【问题标题】:Java connecting to multiple databasesJava连接多个数据库
【发布时间】:2011-12-13 15:26:52
【问题描述】:

我正在创建一个连接到多个数据库的 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是缓存连接还是故障安全?以这种方式创建连接是一个坏主意吗?

【问题讨论】:

  • 您是否尝试将 dbMainConnection 的 catch 范围内的 ds 置空?

标签: java oracle jdbc weblogic


【解决方案1】:

您将一个唯一的数据源(和连接,以及 dbMainConnection)存储在类的 static 变量中。每次有人要求提供数据源时,您都会用新的数据源替换之前的数据源。如果从 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);
        }
    }
}

并让调用者从数据源获取连接,并在他们使用完毕后关闭它。

【讨论】:

  • 太棒了。谢谢您的帮助。显然我是一个java新手,所以感谢清晰的解释和代码。只是为了确保我理解。我摆脱了 dbconnect 类,而是使用 dataSourceUtil 类来获取数据源。然后使用它来创建与不同数据库的连接。后记关闭数据库连接和初始上下文。对吗?
  • 对(除了InitialContext关闭,你不能关闭,但我认为让它打开并不重要)。
【解决方案2】:

您在查找不存在的数据源时捕获了 JNDI 异常,但您的单例仍保留对先前查找的数据源的引用。作为 A.B. Cade 说,异常时或什至在此之前对 ds 的引用为空。

一般来说,使用 Singleton 可能不是最好的主意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 2020-01-23
    • 2016-05-19
    • 2019-07-10
    • 2012-01-06
    相关资源
    最近更新 更多