存储过程越来越多的应用到项目当中了,不罗嗦了先来看看JAVA怎么从oracle接收对象数组。
- --建立oracle对象
- CREATE OR REPLACE TYPE PERSON AS OBJECT (
- --如果你执意使用VARCHAR2有一定几率出现乱码和ASCII码(貌似和驱动有关)
- --为了避免平台,服务器中间件,驱动等等因素而造成的
- --可能出现乱码(无法识别)和以0X开头的16进制ASCII等情况请使用NVARCHAR2
- P_ID NVARCHAR2(32),
- P_NAME NVARCHAR2(16),
- P_AGE NVARCHAR2(24),
- P_PROJECT NVARCHAR2(32) )
- --建立对象数组
- CREATE OR REPLACE TYPE PERSON_TABLE_TYPE IS TABLE OF PERSON
- --建立测试用存储过程
- --PS:这个过程是在我的一个包(TEST.DEMO)里面的,如果单独写成过程请create or replace
- PROCEDURE GETBEAN_OBJTABLE(V_TABLE OUT PERSON_TABLE_TYPE)
- AS
- BEGIN V_TABLE := PERSON_TABLE_TYPE();
- FOR I IN 1 .. 5 LOOP
- V_TABLE.EXTEND; V_TABLE(I) := PERSON(‘23231123232‘||I,
- ‘第‘||I||‘代‘,
- ‘20‘||I,
- ‘2010-1-1‘||I);
- END LOOP;
- END;
JAVA端
- //如果你使用JDBC,
- //你可以强转conn为oracleConnection也可以像我一样强转CallableStatement为OracleCallableStatement。
- //但如果你使用诸如tomcat的DBCP等连接池请首先转换为native连接,然后转换为oracle连接,直接强转是无效的!
- //(最后释放关闭的连接是连接池的连接而不是oracle的连接)
- conn = DbHelperImpJdbc.getInstance().getConn();
- cs = (OracleCallableStatement) conn.prepareCall("{call PKG_DEMO.GETBEAN_OBJTABLE(?)}");
- cs.registerOutParameter(1, OracleTypes.ARRAY, "PERSON_TABLE_TYPE".toUpperCase());
- ARRAY obj = (ARRAY) cs.getArray(1);
- Datum[] datas = obj.getOracleArray();//获取对象
- //遍历对象数组
- for(int i=0;i<datas.length;i++){
- System.out.println("对象"+i);
- //获取属性
- Object[] beanAttributes = ((STRUCT) datas[i]).getOracleAttributes();
- //遍历属性
- for(int m=0;m<beanAttributes.length;m++){
- System.out.println(" "+beanAttributes[m]);
- }
- }
打印结果:
对象0
232311232321
第1代
201
2010-1-11
对象1
232311232322
第2代
202
2010-1-12
对象2
232311232323
第3代
203
2010-1-13
对象3
232311232324
第4代
204
2010-1-14
对象4
232311232325
第5代
205
2010-1-15
接下来我们来看看怎么从过程中接收二维数组,由于二维数组的接收网上资料很少,通过自己的研究发现二维数组可以先转换成一维数组,然后每个元素再逆向转换成Oracle.ARRAY,再然后按照一维数组如法炮制。
- --建立一维数组
- --PS也请使用NVARCHAR2
- CREATE OR REPLACE TYPE TYPE_VARCHAR IS TABLE OF NVARCHAR2(2000)
- --建立二维数组
- CREATE OR REPLACE TYPE TYPE_VARCHAR_TABLE IS TABLE OF TYPE_VARCHAR
- --建立测试用过程
- PROCEDURE GETBEAN_ARRAYTABLE(V_TABLE OUT TYPE_VARCHAR_TABLE)
- AS
- BEGIN
- V_TABLE:=TYPE_VARCHAR_TABLE();
- FOR I IN 1 .. 5 LOOP
- V_TABLE.EXTEND;
- V_TABLE(I):=NEW TYPE_VARCHAR(‘23231123232‘||I,
- ‘ 第‘||I||‘代‘,
- ‘20‘||I,
- ‘2010-1-1‘||I);
- END LOOP;
- END;
JAVA端
- conn = DbHelperImpJdbc.getInstance().getConn();
- cs = (OracleCallableStatement) conn.prepareCall("{call PKG_DEMO.GETBEAN_ARRAYTABLE(?)}");
- cs.registerOutParameter(1, OracleTypes.ARRAY, "TYPE_VARCHAR_TABLE".toUpperCase());
- cs.execute();
- ARRAY obj = (ARRAY) cs.getArray(1);
- //获取第一维度
- Object[] firstDimension=(Object[]) obj.getArray();
- for(int i=0;i<firstDimension.length;i++){
- System.out.println("对象"+i);
- //将第一维度元素转成ARRAY之后获取数组再将该数组元素转换成数组,
- //这便是第二维度数组
- Object[] secondDimension=(Object[]) ((ARRAY)firstDimension[i]).getArray();
- for(int m=0;m<secondDimension.length;m++){
- System.out.println(" "+secondDimension[m]);
- }
- }
打印结果同上。
总结:使用二维数组比对象数组灵活的多,如果我们要为返回结果集中删减字段,就必须要先去更改oracle的对象,这样很不灵活。而二维数组的可伸缩性就非常好了。