Oracle存储过程及Java调用(二)

2015-07-16 12:08:05 · 作者: · 浏览: 9
ter.svntesr;


import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


import com.lofter.bean.ProcedureBean;


public class ProcedureTest3 {


?/**
? * @param args
? */
?public static void main(String[] args) {
? try {?
? ?
? ? ? ? ? ? Class.forName("oracle.jdbc.driver.OracleDriver");?
?
? ? ? ? ? ? String url = "jdbc:oracle:thin:@localhost:1521:orcl";?
?
? ? ? ? ? ? //网上很多卡在获取con这个地方的,我最初也是,说是什么jar包问题,删掉class12啊,什么oracle与apache连接池冲突啊,但是我其实是存储过程没写对,最后绕了一圈回来还是用的这种方法测试通过,并没有加((org.apache.commons.dbcp.PoolableConnection) conn).getInnermostDelegate()
? ? ? ? ? ? Connection con = DriverManager.getConnection(url, "system", "a");?
?
? ? ? //? ? ? PreparedStatement pstmt = null;?
? ? ? ? ? ? CallableStatement cs = null;
? ? ? ? ? ? ResultSet rs=null;
? ? ? ? ? ?
? ? ? ? ? ? List list = new ArrayList();
? ? ? for (int i = 1; i <= 12; i++) {
? ? ? ?String r = i + "";
? ? ? ?list.add(new ProcedureBean("1", r, "0"));
? ? ? }
? ? ?//?list.add(new ProcedureBean("1","5f60b0f0-03d9-4671-b945-936fe821fe19", "0"));
? ? ?
? ? ? //如果存储过程是用我这种对象数组as object类型,则java调用这一步必不可少,这是对之前在pl/sql中声明的tp_arr3 类型的映射,表示在pl/sql中去匹配你自定义的类型
? ? ? //还有注意要大写,不然可能会报“无效名称模式”
? ? ? StructDescriptor recDesc = StructDescriptor.createDescriptor(
? ? ?"TP_ARR3", con);


? ? ? //这一步是将你自定义的类型转化成oracle自己的类型,即STRUCT,相当于一个Object类,因为oracle的开发人员也不知道你会定义一个什么名字的类型,反正只用提供一个规则,最后大家都照着这个规则来转化就是了
? ?ArrayList pstruct = new ArrayList();
? ?for (ProcedureBean pb : list) {
? ? System.out.println(pb);
? ? Object[] objs = new Object[3];
? ? objs[0] = pb.getUserid();
? ? objs[1] = pb.getTopicid();
? ? objs[2] = pb.getRecord();
? ? STRUCT item = new STRUCT(recDesc, con, objs);
? ? pstruct.add(item);
? ?}
? ?
? ?//这是第二步映射,映射我在oracle中自定义的tp_arr_tbl3类型,注意也要大写,网上也有说要加包名,不是同一个用户要加用户前缀什么的,我没有加,测试也通过,可能不是极端情况吧
? ?oracle.sql.ArrayDescriptor desc = oracle.sql.ArrayDescriptor.createDescriptor("TP_ARR_TBL3", con);?
? ?
? ? ? ? ? ? oracle.sql.ARRAY array = new oracle.sql.ARRAY(desc, con, pstruct.toArray());
? ? ? ? ? ?
? ? ? ? ? ? //也有说调用的时候要加包名的
? ? ? ? ? ? cs = con.prepareCall("{call findRecord(?,?)}");
? ? ? ? ? ?
? ? ? ? ? ? //设置参数这里,1、2分别对应存储过程findRecord(?,?)中参数的位置,注意位置不要错了
? ? ? ? ? ? cs.setArray(1, array);
? ? ? ? ? ? cs.registerOutParameter(2, OracleTypes.CURSOR);
? ? ? ? ? ? cs.execute();
? ? ? ? ? ? rs=(ResultSet) cs.getObject(2);?//取数据也是根据对应参数位置来的
? ? ? ? ? ?
? ? ? ? ? ? while( rs.next() ){
? ? ? ? ? ? ?System.out.println("result : \t" + rs.getString(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
? ? ? ? ? ? }
? ? ? ? ? ? con.commit();
? ? ? ? } catch (Exception e) {?
?
? ? ? ? ? ? e.printStackTrace();?
?
? ? ? ? }?
?
? ? }? ?
?}


Java调用注意:基本上注意事项都以注释的方式写在代码里了,也有可能没想起来,很多bug信息由于测试通过心切,没能及时复制下来。注意不要导错包


2.错误信息“Message file 'oracle.jdbc.driver.Messages' is missing.”,可能是你写错了或类型与oracle中不匹配,不要去找什么jar包啊什么的,网上信息也不多,我在这绕了好久,多检查一下上面提到的加包名、大小写、转类型什么的;


还有其他没想起来或没碰到的bug只有亲们多结合错误信息猜测,多动手测测,相信就会迎刃而解了。


测试的javaBean:


package com.lofter.bean;


import java.io.Serializable;


public class ProcedureBean implements Serializable {


?private static final long serialVersionUID = 809894604693791308L;
?private String userid;
?private String topicid;
?private String record;


?public ProcedureBean() {
? super();
?}


?public ProcedureBean(String userid, String topicid, String record) {
? super();