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

--点赞关系表
create table tb_praise_rel(
      id varchar2(40) primary key,
      userid varchar2(40),            --用户id
      topicid  varchar2(40),            --话题id
      remarks1 varchar2(3000),        --备用字段
      remarks2 varchar2(3000),
      remarks3 varchar2(3000)
);

再上Java调用代码:

package com.lofter.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 Oracle.jdbc.OracleTypes;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;

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<ProcedureBean> list = new ArrayList<ProcedureBean>();
      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<STRUCT> pstruct = new ArrayList<STRUCT>();
   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(); 
 
        } 
 
    }   
 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/a41a2c2e77c33527d70712801eb8cab3.html