对表里字段类型为:DATE
不同版本的OJDBC驱动包使用getObject出来的类型不同。
ojdbc14_10_2_0_4.jar出来的是java.sql.Date
ojdbc14.jar出来的是java.sql.Timestamp
但是有的时候,同一个应用里面要访问不同版本的ORACLE数据库,这时就需要同一个应用里面加载两个版本的OJDBC。
A1
public class A1 { public static void test1() throws Exception { URL[] urls=new URL[2]; urls[0]=new File("E:\\workspace-nfjd\\testrealpath\\work\\ojdbc14.jar").toURL(); urls[1]=new File("E:\\workspace-nfjd\\testrealpath\\build\\").toURL(); URLClassLoader cl1=new URLClassLoader(urls, null); cl1.loadClass("oracle.jdbc.OracleDriver").newInstance(); Object obj1=cl1.loadClass("JdbcTest").newInstance(); Method m1 = obj1.getClass().getMethod("executeJdbc", new Class[]{}); m1.invoke(obj1,new Object[]{}); } public static void test2() throws Exception { URL[] urls=new URL[2]; urls[0]=new File("E:\\workspace-nfjd\\testrealpath\\build\\ojdbc14_10_2_0_4.jar").toURL(); urls[1]=new File("E:\\workspace-nfjd\\testrealpath\\build\\").toURL(); URLClassLoader cl1=new URLClassLoader(urls, null); cl1.loadClass("oracle.jdbc.OracleDriver").newInstance(); Object obj1=cl1.loadClass("JdbcTest").newInstance(); Method m1 = obj1.getClass().getMethod("executeJdbc", new Class[]{}); m1.invoke(obj1,new Object[]{}); } public static void main(String[] args) throws Exception { test1(); test2(); } }
JdbcTest
public class JdbcTest { static{ } public void executeJdbc() { try { System.out.println(JdbcTest.class.getClassLoader()); Connection conn = null; PreparedStatement ptmt = null; ResultSet rs = null; conn = DriverManager.getConnection("jdbc:oracle:thin:@10.1.252.80:1521:newngboss", "so1", "so1"); ptmt = conn .prepareStatement("select ROWID,t.* from BAT_PRE_AUTHOR_TMP t where mod(BAT_PRE_AUTHOR_TMP_ID,2)=1 and check_state=1 and rownum <=100 "); ptmt.setFetchSize(100); rs = ptmt.executeQuery(); A1 a = null; while (rs.next()) { System.out.println(rs.getObject("VALID_DATE").getClass()); } } catch (Exception e) { e.printStackTrace(); } } }
注:
一、java.sql.Connection、java.sql.DriverManager加载了几份?
System.out.println(Connection.class.getClassLoader()+":"+ conn+"==="+conn.getClass().getClassLoader()); 结果为: null:oracle.jdbc.driver.OracleConnection@12a0f6c===java.net.URLClassLoader@4f1d0d null:oracle.jdbc.driver.T4CConnection@ce2187===java.net.URLClassLoader@1f78ef1 所以: Connection的加载器还是JRE的加载器 Connection的实例加载器是自己的加载器
所以只加载了一份,其还是由JRE的加载器加载。
二、java.sql.DriverManager里面的getCallerClass(callerCL, di.driverClassName ) != di.driverClass作用是?
因为DriverManager只有一个实例,在加载JDBC驱动时,都会执行DriverManager.registerDriver(m_defaultDriver);即会将所有类加载器加载的驱动放入DriverManager.readDrivers里面。
为了保证各个类加载器里面的JDBC实例互不影响,所以在getConnection、getDrivers、getDriver时,通过if (getCallerClass(callerCL, di.driverClassName ) != di.driverClass )过滤了不是自己类加载器加载的驱动。
三、
urls[0]=new URL("file:///E:/workspace-nfjd/testrealpath/work/ojdbc14.jar");
urls[0]=new File("E:\\workspace-nfjd\\testrealpath\\work\\ojdbc14.jar").toURL();
以上两个是等价的。即URL必须协议开头。
最好用:
urls[0]=new File("E:\\workspace-nfjd\\testrealpath\\build\\ojdbc14_10_2_0_4.jar").toURI().toURL();
因为第二种过时了。