今天在做移植java项目到云平台的工作,遇到了执行数组参数的存储过程的问题。先介绍一下怎么样执行数组参数的存储过程。
//创建descriptor,typeArrayName是数据库中数组变量的名称
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor(typeArrayName, conn);
//将descriptor和valueObject mapping形成一个Array对象
ARRAY array = new ARRAY(descriptor, oracleConn, valueObject);
//callTest是CallableStatement对象,调用setObject方法设置参数
callTest.setObject(1, (Object) array);
callTest.execute();
问题的原因是ArrayDescriptor.createDescriptor方法中将conn会转换成oracle.jdbc.OracleConnection对象.
但是Cloud平台返回的conn是内部封装好的GenPooledConnection对象。通过反编译发现GenPooledConnection对象继承了Connection对象。但是转成oracle.jdbc.OracleConnection对象时就会抛出类型不匹配的错误。并且在new GenPooledConnection对象的时候,将Connection对象传进来并保存到变量c中,因为c是私有成员变量。接下来通过反射拿到c。
public class GenPooledConnection
/* */ implements Connection, GenCacheable
/* */ {
private Connection c;
/* */ protected GenPooledConnection(String name, Connection c, Stack free, Hashtable active, long timeOut, boolean trace)
/* */ {
/* 36 */ this.id = new Integer(nextId++);
/* 37 */ this.name = name;
/* 38 */ this.c = c;
/* 39 */ this.free = free;
/* 40 */ this.active = active;
/* 41 */ this.timeOut = timeOut;
/* 42 */ this.trace = trace;
/* 43 */ this.starttime = System.currentTimeMillis();
/* 44 */ touch();
/* */ }
。。。
}
public Connection getOracleConnection(Connection conn) throws SWTException
{
Class<?> clazz;
Connection c = null;
try
{
clazz = Class.forName("com.ssc.faw.util.GenPooledConnection");
Field field = clazz.getDeclaredField("c");
field.setAccessible(true);
c = (Connection) field.get(conn);
}
catch (Exception ex)
{
Logger.error("Error Cause::" + ex.getMessage());
throw new SWTException(ex);
}
return c;
}
其实通过反射去拿私有函数也是没办法的事,谁让不提供公有的方法去获得connection对象呢,和TL讨论后,他也没办法,而且他也早就这样做过了,哈哈