服务器为Tomcat5.0,配置好Oracle9.2的JNDI数据源,通过Context来获取javax.sql.DataSource,
然后再获取Connection。Oracle中表TEST001的字段G是TIMESTAMP类型,示例代码如下,注释为
其简单输出。
InitialContext initCtx = ...
Context ctx = initCtx.lookup(...);
DataSource ds = (DataSource)ctx.lookup(...);
Connection conn = ds.getConnection();//已经获取了Connection
PreparedStatement ps = conn.prepareStatement("select g from test001 where a='ccc'");
ResultSet rs = ps.executeQuery();
while(rs.next()){
Object obj = rs.getObject(1);
out.println("getG:"+obj.getClass().getName()+"<BR>");//oracle.sql.TIMESTAMP
out.println("getG:"+obj.getClass().isInstance(obj)+"<BR>");//true
out.println("getG:"+oracle.sql.TIMESTAMP.class.isInstance(obj)+"<BR>");//false
out.println("getG:"+oracle.sql.TIMESTAMP.class.equals(obj.getClass())+"<BR>");//false
out.println("getG:"+oracle.sql.TIMESTAMP.class.equals(oracle.sql.TIMESTAMP.class)+"<BR>");//true
out.println("getG:"+obj.getClass().equals(obj.getClass())+"<BR>");//true
out.println("getG:"+obj.getClass().equals(oracle.sql.TIMESTAMP.class)+"<BR>");//false
//out.println("getG:"+(oracle.sql.TIMESTAMP)obj+"<BR>");//该语句将抛出ClassCastException异常
}
conn.close();
请高手给解决一下这个问题,否则Oracle中的TIMESTAMP字段就永远无法取得正常值了。
必要说明:Connection如果是从DriverManager.getConnction(...)获取的话没有这个问题。
怀疑是commons-dbcp的问题。
然后再获取Connection。Oracle中表TEST001的字段G是TIMESTAMP类型,示例代码如下,注释为
其简单输出。
InitialContext initCtx = ...
Context ctx = initCtx.lookup(...);
DataSource ds = (DataSource)ctx.lookup(...);
Connection conn = ds.getConnection();//已经获取了Connection
PreparedStatement ps = conn.prepareStatement("select g from test001 where a='ccc'");
ResultSet rs = ps.executeQuery();
while(rs.next()){
Object obj = rs.getObject(1);
out.println("getG:"+obj.getClass().getName()+"<BR>");//oracle.sql.TIMESTAMP
out.println("getG:"+obj.getClass().isInstance(obj)+"<BR>");//true
out.println("getG:"+oracle.sql.TIMESTAMP.class.isInstance(obj)+"<BR>");//false
out.println("getG:"+oracle.sql.TIMESTAMP.class.equals(obj.getClass())+"<BR>");//false
out.println("getG:"+oracle.sql.TIMESTAMP.class.equals(oracle.sql.TIMESTAMP.class)+"<BR>");//true
out.println("getG:"+obj.getClass().equals(obj.getClass())+"<BR>");//true
out.println("getG:"+obj.getClass().equals(oracle.sql.TIMESTAMP.class)+"<BR>");//false
//out.println("getG:"+(oracle.sql.TIMESTAMP)obj+"<BR>");//该语句将抛出ClassCastException异常
}
conn.close();
请高手给解决一下这个问题,否则Oracle中的TIMESTAMP字段就永远无法取得正常值了。
必要说明:Connection如果是从DriverManager.getConnction(...)获取的话没有这个问题。
怀疑是commons-dbcp的问题。
出于通用性,他们继承自 java.sql.Timestamp
所以你转化为oracle.sql.TIMESTAMP 会抛出异常如果你用Weblogic的,你更不能直接用Oracle.sql 了,而必须用weblogc.thin.,,,, 之类的!
我知道它是进行了封装,不知道你有没有看过commons-dbcp 和 commons-pool的源代码,
你会发现,从这里获得的ResultSet的确是经过封装的,但是请注意,他封装时,只是将
实际生成的ResultSet传入到它的封装类中作为私有变量,然后针对所有封装类调用的方法
都是直接从调用私有的这个ResulstSet的方法,因此,从道理上来讲,再怎么封装,它
实现的功能都还是原来生成的ResultSet的功能;
其次,请你注意一下继承体系,oracle.sql.TIMESTAMP 继承oracle.sql.Datum,
oracle.sql.Datum 继承 Object,然后请再看清楚,我在这里根本就没有出现强制转换
成java.sql.Timestamp的,不要答非所问。最后,再说明一下,我提这个问题的要点:
rs.getObject(1).getClass().getName()返回的是oracle.sql.TIMESTAMP,
那么为什么这样的强制转换:
(oracle.sql.TIMESTAMP)rs.getObject(1)
会抛出ClassCastException?
如:if(obj instanceof oracle.sql.TIMESTAMP)
out.println("getG:"+(oracle.sql.TIMESTAMP)obj+" <BR> ");
out.println(oracle.sql.TIMESTAMP.class.getClassLoader()+"<BR>"); // Line 2发现,Line 1 的ClassLoader顺序为:StandardClassLoader -> sun.misc.Launcher$AppClassLoader ;
Line 2 的ClassLoader顺序为:WebClassLoader --> StandardClassLoader -> sun.misc.Launcher$AppClassLoader ;
确实表明是他们的 ClassLoader 是不一样的,你的结论完全正确,谢谢!
# prop.put ("oracle.jdbc.V8Compatible", "true"); // so getObject returns Timestamp!
# prop.put ("user", "scott");
# prop.put ("password", "tiger");
# String url ="jdbc:oracle:thin:@host:port:sid";
conn.prepareStatement("select g from test001 where a='ccc'",ResultSet.TYPE_SCROLL_INSENSITIVE);
就可以了,这样可以防止Oracle的驱动对字段的类型进行修改,以仍然保持JDBC类型。