2010-10-04 36 views
4

我正在構建一個正在整理來自多個數據源的數據的應用程序。在這些數據源中,我們有多個Oracle正在運行的實例。哪個可能? 1)連接到Oracle 8i w/ojdbc5或ojdbc6 2)多個ojdbc jar

我發現我可以連接到我的Oracle 8i的實例的唯一方法是通過使用將ojdbc14.jar及以下:

String driver = "oracle.jdbc.OracleDriver"; 
String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=$HOST)(PORT=$PORT)))(CONNECT_DATA=(SID=$SID)))" 
Class.forName(driver); 
Connection c = DriverManager.getConnection(url, $USER, $PASSWORD); 
c.close(); 

當我嘗試更新到ojdbc5.jarojdbc6.jar,使用相同的代碼,我得到一個ArrayIndexOutofBoundsException。同上,如果我只使用URL「jdbc:oracle:thin:$ user/$ password @ $ host:$ port:$ sid」,這對我連接的更新的Oracle實例起作用。

我寧願不被鎖定爲具有使用舊將ojdbc14.jar(尤其是因爲我使用Java 6)我有可能在今後相當很快支持更高的Oracle數據庫。

所以,我希望兩個中的一個場景是可能的:

1)有我只是俯瞰一個連接字符串,可用於連接到Oracle 8i的W /最近OJDBC罐子。

2)我可以對我的類路徑多個OJDBC罐子,這樣我可以使用異常的基礎上ojdbc14.jar的ojdbc6.jar其他任何地方。當然,這裏的技巧是弄清楚如何指定連接需要使用哪個jar來使用「oracle.jdbc.OracleDriver」類。

有什麼想法?

回答

4

出於好奇,我通過隔離類加載器實現了你的第二種方法。這似乎是工作:

public class DriverWrapper implements Driver { 
    private Driver target; 
    private String fakePrefix; 
    private String realPrefix; 

    protected DriverWrapper(Driver target, String fakePrefix, String realPrefix) { 
     this.target = target; 
     this.fakePrefix = fakePrefix; 
     this.realPrefix = realPrefix; 
    } 

    public static void loadDriver(URL[] classPath, String className, String fakePrefix, String actualPrefix) 
     throws Exception{ 

     URLClassLoader cl = new URLClassLoader(classPath, DriverWrapper.class.getClassLoader()); 
     Class<?> c = cl.loadClass(className);   

     // It's rather rude, but we haven't access to the existing instance anyway 
     Driver d = (Driver) c.newInstance(); 
     Driver w = new DriverWrapper(d, fakePrefix, actualPrefix); 

     // We don't care about already registerd instance, 
     // because driver loaded in isolated classloader 
     // is not visible to the rest of application, see DriverManager javadoc 
     DriverManager.registerDriver(w); 
    } 

    private String resolveURL(String url) { 
     if (url.startsWith(fakePrefix)) { 
      return realPrefix + url.substring(fakePrefix.length()); 
     } else { 
      return null; 
     } 
    } 

    public boolean acceptsURL(String url) throws SQLException { 
     url = resolveURL(url); 
     if (url == null) { 
      return false; 
     } else { 
      return target.acceptsURL(url); 
     } 
    } 

    public Connection connect(String url, Properties info) throws SQLException { 
     url = resolveURL(url); 
     if (url == null) { 
      return null; 
     } else { 
      return target.connect(url, info); 
     } 
    } 

    public int getMajorVersion() { 
     return target.getMajorVersion(); 
    } 

    public int getMinorVersion() { 
     return target.getMinorVersion(); 
    } 

    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { 
     return target.getPropertyInfo(url, info); 
    } 

    public boolean jdbcCompliant() { 
     return target.jdbcCompliant(); 
    } 

} 

用法如下(司機罐子不應該位於主類路徑):

DriverWrapper.loadDriver(new URL[] { new File("ojdbc5.jar").toURL() }, 
    "oracle.jdbc.OracleDriver", "jdbc:oracle5", "jdbc:oracle"); 
DriverWrapper.loadDriver(new URL[] { new File("ojdbc14.jar").toURL() }, 
    "oracle.jdbc.OracleDriver", "jdbc:oracle14", "jdbc:oracle"); 

... DriverManager.getConnection("jdbc:oracle14:...", ...); 
... DriverManager.getConnection("jdbc:oracle5:...", ...); 
+0

謝謝,我給這一個嘗試下機會,我得到! – 2010-11-10 20:42:43

+0

Geez我打算在幾天內實現同樣的事情,非常感謝與我們分享此代碼。 – newhouse 2012-04-26 07:09:13