处理来自SAME VENDOR的多个JDBC驱动程序

时间:2012-03-07 07:50:11

标签: jdbc jar classloader

昨天我遇到了一个大问题。在我目前的项目中,我使用ojdbc6实现Oracle的JDBC进行连接,但我还需要处理例如oracle 8数据库,这对于这个JAR是完全不可能的。 您可以说我应该使用ojdbc14,这对某些测试来说是正确的,但我们假设稍后我将需要处理来自同一供应商的2种数据库,但我们知道没有现有的实现两个,我需要加载那些同时。相同的接口(好吧,不仅仅是相同的接口,相同的类结构,内部只是不同的实现!),相同的URL连接前缀 - > JDBC连接将使用一个驱动程序,但我无法加载其中的多个驱动程序。那么现在呢?

  • 我的第一个想法是使用不同的类加载器加载JAR,也许我可以加载相同的包结构,并且相同的类彼此分开?我真的不这么认为,也许这是我的一个愚蠢的想法。这可能也是一个普遍的问题,以后不仅仅是JDBC驱动程序,所以即使你不能回答我的问题,但你知道这里缺少什么,请告诉我

  • 即使我可以单独加载相同类名的类实现,在创建连接时如何告诉DriverManager使用EXACT驱动程序而不是根据连接url的前缀找到一个? (我的意思是jdbc:oracle:例如,瘦)。

我现在觉得自己是个笨蛋,因为我认为在Java世界中处理这个并不是一个完全不同寻常的想法,但我完全不知道如何处理。

非常感谢您提前

2 个答案:

答案 0 :(得分:6)

你实际上有几个选择:

  1. 您可以尝试从不同的类加载器加载驱动程序。如果您的应用程序中只需要纯JDBC,那将会有效。我怀疑你会让Hibernate使用这样的设置。

    最终,您将需要运行代码,您需要从两个类加载器中查看实例,在这里,您将获得ClassCastException s(两个具有相同完整限定名称的类在从不同的加载时是不同的班级装载机)。

  2. 您可以将应用程序拆分为两个。第二个是一个小型服务器,它从原始应用程序获取命令并将这些命令转换为数据库的JDBC。小型服务器与Oracle 8通信,而您的应用只与一个数据库通信。

    这种方法可以让你将两个问题完全分开,但是你无法在两个数据库上运行连接。

  3. 您可以使用CREATE DATABASE LINK链接新数据库中的旧Oracle 8数据库。这使旧表可见,就像它们是新数据库的一部分一样。您的应用程序只与一个数据库通信,Oracle在内部处理细节。

    也许Oracle 8太老了,不能用,但我肯定会尝试一下。

  4. Oracle JDBC驱动程序与您可能期望的兼容性更高。当你说“这个JAR完全不可能”时,你尝试吗?我过去使用Oracle 10驱动程序连接到Oracle 7。并非所有功能都受支持,但我可以运行标准查询和更新。

答案 1 :(得分:-1)

#jdbc.properties
oracle.driver=oracle.jdbc.OracleDriver
oracle.url=jdbc:oracle:thin:@//localhost/xe
oracle.user=scott
oracle.password=tiger

mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost/sales
mysql.user=root

mssql.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
mssql.url=jdbc:sqlserver://192.168.1.175;databaseName=sales
mssql.user=dbviewer
mssql.password=dbviewer

然后阅读属性文件:

class QueryTest2 {

   public static void main(String[] args) throws Exception{
        Properties settings = new Properties();
        FileInputStream fin = new FileInputStream("jdbc.properties");
        settings.load(fin);
        fin.close();
        String dvr = settings.getProperty(args[0] + ".driver");
        String url = settings.getProperty(args[0] + ".url");
        String usr = settings.getProperty(args[0] + ".user");
        String pwd = settings.getProperty(args[0] + ".password");
        Class.forName(dvr);
        Connection con = DriverManager.getConnection(url, usr, pwd);
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("select pno,price,stock from products");
        while(rs.next()){
            System.out.printf("%d\t%.2f\t%d%n", rs.getInt(1), rs.getDouble(2), rs.getInt("stock"));
        }
        rs.close();
        stmt.close();
        con.close();
    }
}