我正在创建一个连接到多个数据库的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: Unable to resolve ‘jdbc.peterson’. Resolved ‘jdbc’; remaining name ‘peterson’.
这也是我所期待的,但令我困惑的是,它抓住了最后一个良好的连接,这是一个不同的数据库,并处理一切,好像什么也没发生.
谁知道为什么会这样? weblogic是否将连接或某些内容缓存为故障安全?以这种方式创建连接是一个坏主意吗?
解决方法:
您将一个唯一的数据源(和连接,以及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);
}
}
}
让调用者从数据源获取连接,并在完成使用后关闭它.