文档章节

java调用带有自定义类型参数的存储过程

 华航小辉
发布于 2015/05/28 17:45
字数 1344
阅读 84
收藏 0

        最近工作中遇到了这样的一个需求,需要我批量的导入一下数据,但是公司的框架对事务的支持不是很好,所以考虑了之后希望把事务放到数据库中实现,于是就想到了写一个带有数组参数的存储过程,于是在网上找了好多资料,经过自己试验之后,完成了这篇博文,也是我的第一篇博文。在这里插一句题外话:“只要你想去做,努力的去做,我们就可以实现我们的需求!”

        首先、建立一张表userinfo,userid就是身份证号

create table userinfo(
    userid varchar2(20) primary key,
    uname varchar2(20) not null,
    usex number(1) not null,
    uaddr varchar2(100) not null);

       然后、需要在数据库中创建两个type,用来对数据进行封装

        创建的是一个array类型,用来封装java中的一个对象数据

create or replace type array_user as object
(    userid nvarchar2(20),
     uname nvarchar2(20),
     usex number(1),
     uaddr nvarchar2(100)
);

        再创建一个list类型,用来封装多个java对象信息,当list的长度大于5000的时候,就会分批次传递参数执行proc

create or replace tepe list_user as varray(5000) of array_user;

      接下来就是一个重头戏了,存储过程

create or replace procedure proc_user(
        i_array in list_user,
        o_errcode out number,
        o_errdesc out varchar2) is
 v_userid nvarchar2(20);
 v_uname nvarchar2(20);
 v_usex nvarchar2(1);
 v_uaddr nvarchar2(100);
 v_type array_user;
 begin
     for i in 1..i_array.count loop
        v_type:=i_array(i);
        v_userid:=v_type.userid;
        v_uname:=v_type.uname;
        v_usex:=v_type.usex;
        v_uaddr:=v_type.uaddr;
     insert into userinfo 
     values(v_userid,v_uname,v_usex,v_uaddr);
     end loop;
     commit;
     o_errcode:=0;
     o_errdesc:='成功返回';
     Exception
         when Dup_val_on_index then 
             o_errcode:=1;
             o_errdesc:='违反唯一性约束';
         when others then 
             o_errcode:=SQLCODE;
             o_errdesc:=SUBSTR(SQLERRM,1,200);
         rollback;
   end proc_user;

        存储过程写完了,剩下的就是java代码了,调用带自定义类型的存储过程

package elmp_test;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import oracle.jdbc.OracleCallableStatement;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;
    @SuppressWarnings("unchecked")  
    public class TestProc {  
      
        public static void main(String[] args) { 
        	String downloadpath = "http://www.test.com";
            List arrayL = new ArrayList();
            User u = new User();
            u.setUserid("333");
            u.setUname("xiaohua");
            u.setUsex(1);
            u.setUaddr("北京市海淀区");
            arrayL.add(u);
            User u1 = new User();
            u1.setUserid("444");
            u1.setUname("xiaohui");
            u1.setUsex(0);
            u1.setUaddr("北京市昌平区");
            arrayL.add(u1);    
            
            try {  
                /* 
                 * 记得判断一下list集合的大小、如果集合大于你在数据设置的数组大小了、那么就要分批次提交 
                 * 我的是y_Oracle_LIST AS VARRAY(5000)  
                 * 那么当list集合的值等于5000的时候就入库了、 
                 * 然后剩下的数据又从新用一个list来装、在继续判断...... 
                 * 这里只是简单的演示、就不具体操作判断了 
                 */  
                int backVal = newTest(arrayL);  
                System.out.println(backVal==0?"成功!":"失败!");  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
        }  
        /** 
         * 将java中的arrayList转化 
         * @param con 数据库连接对象 
         * @param Oraclelist 数据数组类型名称 
         * @param objlist 要存储的list对象 
         * @return oracle.sql.ARRAY 
         * @throws Exception 
         */  
        private static ARRAY getOracleArray(Connection con, String Oraclelist,  
                List objlist) throws Exception {  
            ARRAY list = null;  
            if (objlist != null && objlist.size() > 0) {  
                /** 
                 * 必须大写类型名称 
                 * 否则会报错:java.sql.SQLException: 无效的名称模式: M_ORDER.yoracleobject 
                 */  
                StructDescriptor structdesc = new StructDescriptor(  
                        "ARRAY_USER", con);   
                STRUCT[] structs = new STRUCT[objlist.size()];  
                Object[] result = null;  
                for (int i = 0; i < objlist.size(); i++) {  
                    result = new Object[4];   
                    User t = (User)(objlist.get(i));  
                    result[0] = t.getUserid();  
                    result[1] = t.getUname();  
                    result[2] = t.getUsex();
                    result[3] = t.getUaddr();;  
                    /* 
                     * 一定要记得导入orai18n.jar 
                     * 否则一遇到字符串就乱码、添加不到数据 
                     */  
                    structs[i] = new STRUCT(structdesc, con, result);  
                }  
                ArrayDescriptor desc = ArrayDescriptor.createDescriptor(Oraclelist,  
                        con);  
                list = new ARRAY(desc, con, structs); 
                
            } else {  
                ArrayDescriptor desc = ArrayDescriptor.createDescriptor(Oraclelist,  
                        con);  
                STRUCT[] structs = new STRUCT[0];  
                list = new ARRAY(desc, con, structs);  
            }  
            return list;  
        }   
          
        /** 
         * 入库 
         * @param peoleList 要存储的list对象 
         * @return 
         * @throws SQLException 
         */  
        public static int newTest(List peoleList) throws SQLException{  
            Connection con = null;  
            CallableStatement stmt = null;  
            int backVal = -1; 
            String message = null;
            try {  
                DbUtil d = new DbUtil();  
                con = d.getCon();  
                if (con != null) {  
                    stmt = con.prepareCall("{call proc_user(?,?,?)}");  
                    ARRAY adArray = getOracleArray(con, "LIST_USER",peoleList);  
                    ((OracleCallableStatement) stmt).setARRAY(1, adArray);  
                    stmt.registerOutParameter(2, java.sql.Types.INTEGER);
                    stmt.registerOutParameter(3, java.sql.Types.LONGNVARCHAR);
                    stmt.execute();   
                    backVal = stmt.getInt(2);
                    message = stmt.getString(3);
                }  
            } catch (Exception e) {  
                e.printStackTrace();   
            } finally {  
                if(stmt!=null){  
                    stmt.close();  
                }  
                if(con!=null){  
                    con.close();  
                }  
            }  
            return backVal;  
        }  
    }

        DButils工具类

package elmp_test;

import java.io.IOException;  
import java.io.InputStream;  
import java.sql.Connection;  
import java.sql.DriverManager;  
import java.util.Properties; 
import oracle.jdbc.driver.*;

  
@SuppressWarnings("unused")
public class DbUtil {  
    static Properties properties = null;  
  
    public DbUtil() {  
        // 读取.properties文件的信息  
        properties = new Properties();  
        InputStream in = getClass().getResourceAsStream("/elmp/test/oracleproceduretest/ordermanager.properties");  
        try {  
            properties.load(in);    
        } catch (IOException ex) {  
            System.out.println(ex.getMessage());  
            ex.printStackTrace();  
        }  
    }  
      
    /** 
     * <LI>获取连接对象</LI> 
     *  
     * @return 
     */  
     public Connection getCon() {  
            Connection connection = null;    
            try {  
                String url=properties.getProperty("jdbc.url");  
                String user=properties.getProperty("jdbc.username");  
                String pwd=properties.getProperty("jdbc.password");  
                String driver=properties.getProperty("jdbc.driverClassName");  
                Class.forName(driver);                   
                connection = DriverManager.getConnection(url, user, pwd);  
            } catch (Exception err) {  
                System.out.println("错误:ConDB-->getCon()____JDBC连接失败!");  
                err.printStackTrace();  
                return null;  
            }  
            return connection;  
    }    
}

        properites

    

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@//192.168.225.132:1521/orcl
jdbc.username=hc
jdbc.password=hctest

    最后说明:

            之前在网上查到的相应的代码,在执行的时候老师出错,原因是java程序调用存储过程时,参数没有赋上值,导致无法插入null值,原因是因为array_user中的字段类型,如果有varchar2类型的,请改成nvarchar2类型,这样就可以神奇的赋值了,没有错误的感觉就是爽啊!

            要有一颗发现问题,解决问题的心,这样我们才可以在技术的道路上,走的更远,更远!

© 著作权归作者所有

共有 人打赏支持
粉丝 1
博文 1
码字总数 1344
作品 0
昌平
Spring JdbcTemplate方法详解

qldbFunctionSql); String createHsqldbProcedureSql = "CREATE PROCEDURE PROCEDURE_TEST" + "(INOUT inOutName VARCHAR(100), OUT outId INT) " + "MODIFIES SQL DATA " + "BEGIN ATOMIC "......

The-Start
2013/12/18
0
0
java实现调用Mysql存储过程分析代码

数据库的测试代码如下 : 1、新建表test,sql代码如下: create table test(field1 int not null)TYPE=MyISAM ;insert into test(field1) values(1); 2、删除已存在的存储过程,代码如下: de...

afreon
2015/06/01
0
0
spring中的JdbcTemplate简单记录

JdbcTemplate主要提供以下五类方法: execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句; update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate...

刘谱_smile
2015/07/15
0
0
Spring JdbcTemplate方法详解

JdbcTemplate主要提供以下五类方法: execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句; update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate...

zqcju
2014/06/13
0
6
JDBC基础教程之CallableStatement

概述      CallableStatement 对象为所有的 DBMS 提供了一种以标准形式调用已储存过程的方法。已储存过程储存在数据库中。对已储存过程的调用是 CallableStatement对象所含的内容。这种调...

xiahuawuyu
2012/07/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

初级开发-编程题

` public static void main(String[] args) { System.out.println(changeStrToUpperCase("user_name_abc")); System.out.println(changeStrToLowerCase(changeStrToUpperCase("user_name_abc......

小池仔
今天
4
0
现场看路演了!

HiBlock
昨天
14
0
Rabbit MQ基本概念介绍

RabbitMQ介绍 • RabbitMQ是一个消息中间件,是一个很好用的消息队列框架。 • ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的s...

寰宇01
昨天
9
0
官方精简版Windows10:微软自己都看不过去了

微软宣布,该公司正在寻求解决方案,以减轻企业客户的Windows 10规模。该公司声称,企业客户下载整个Windows 10文件以更新设备既费钱又费时。 微软宣布,该公司正在寻求解决方案,以减轻企业...

linux-tao
昨天
19
0
TypeScript基础入门之JSX(二)

转发 TypeScript基础入门之JSX(二) 属性类型检查 键入检查属性的第一步是确定元素属性类型。 内在元素和基于价值的元素之间略有不同。 对于内部元素,它是JSX.IntrinsicElements上的属性类型...

durban
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部