文档章节

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

 华航小辉
发布于 2015/05/28 17:45
字数 1344
阅读 73
收藏 0
点赞 0
评论 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
昌平
Java注解(Annotation)详解

Java注解(Annotation)详解 1.Annotation的概念 An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may......

幻海流心 ⋅ 05/23 ⋅ 0

Scala笔记整理(一):scala基本知识

[TOC] Scala简介 Scala是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。 Scala运行在Java虚拟机上,并兼容现有的Java程序。 Scala源代码被...

xpleaf ⋅ 04/18 ⋅ 0

java集合入门和深入学习,看这篇就差不多了

集合框架: Java中的集合框架大类可分为Collection和Map;两者的区别: Collection是单列集合;Map是双列集合 Collection中只有Set系列要求元素唯一;Map中键需要唯一,值可以重复 Collecti...

sihailoveyan ⋅ 05/04 ⋅ 0

MyBatis传入参数与parameterType

传入简单类型 Java代码: MAPPER : 2. 传入List JAVA代码: 单独传入list时,foreach中的collection必须是list,不不管变量的具体名称是什么。比如这里变量名为idList, collection却是list。 ...

为了美好的明天 ⋅ 05/17 ⋅ 0

Android JNI学习(三)——Java与Native相互调用

本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Native相互调用 Android JNI学习(四)——JNI的常用方法...

隔壁老李头 ⋅ 05/09 ⋅ 0

JAVA虚拟机 JVM 详细分析 原理和优化(个人经验+网络搜集整理学习)

JVM是java实现跨平台的主要依赖就不具体解释它是什么了 ,简单说就是把java的代码转化为操作系统能识别的命令去执行,下面直接讲一下它的组成 1.ClassLoader(类加载器) 加载Class 文件到内...

小海bug ⋅ 06/14 ⋅ 0

通过 HttpAuthenticationMechanism 执行 Web 身份验证

通过 Java EE 8 中新的注解驱动的 HTTP 身份验证机制执行经典和自定义的 Servlet 身份验证 系列内容: 此内容是该系列 4 部分中的第 # 部分: Java EE 8 Security API 入门,第 2 部分 http...

Alex Theedom ⋅ 04/02 ⋅ 0

Java编程语言:Java的类型转换与多态

对于Java语言应该都不陌生,今天我们就将Java中的入门部分概念做一具体的讲解一下。 1.什么叫JVM,JRE,JDK? JRE 全称为JavaRunningEnvironment,就是我们所说的java运行环境,由java虚拟机和一...

启示录是真的 ⋅ 05/22 ⋅ 0

类加载器ClassLoader-1

一, 类加载器深入剖析 1,Java虚拟机与程序的生命周期 在如下几种情况下,Java虚拟机将结束生命周期: –执行了System.exit()方法 –程序正常执行结束 –程序在执行过程中遇到了异常或错误而...

康熙兄弟 ⋅ 06/02 ⋅ 0

Java堆和栈的区别和介绍以及JVM的堆和栈

Java堆和栈的区别和介绍以及JVM的堆和栈 一、Java的堆内存和栈内存 Java把内存划分成两种:一种是堆内存,一种是栈内存。 堆:主要用于存储实例化的对象,数组。由JVM动态分配内存空间。一个...

代金券优惠 ⋅ 05/24 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

RabbitMQ学习以及与Spring的集成(三)

本文介绍RabbitMQ与Spring的简单集成以及消息的发送和接收。 在RabbitMQ的Spring配置文件中,首先需要增加命名空间。 xmlns:rabbit="http://www.springframework.org/schema/rabbit" 其次是模...

onedotdot ⋅ 27分钟前 ⋅ 0

JAVA实现仿微信红包分配规则

最近过年发红包拜年成为一种新的潮流,作为程序猿对算法的好奇远远要大于对红包的好奇,这里介绍一种自己想到的一种随机红包分配策略,还请大家多多指教。 算法介绍 一、红包金额限制 对于微...

小致dad ⋅ 39分钟前 ⋅ 0

Python 数电表格格式化 xlutils xlwt xlrd的使用

需要安装 xlutils xlwt xlrd 格式化前 格式化后 代码 先copy读取的表格,然后按照一定的规则修改,将昵称中的学号提取出来替换昵称即可 from xlrd import open_workbookfrom xlutils.copy ...

阿豪boy ⋅ 今天 ⋅ 0

面试题:使用rand5()生成rand7()

前言 读研究生这3 年,思维与本科相比变化挺大的,这几年除了看论文、设计方案,更重要的是学会注重先思考、再实现,感觉更加成熟吧,不再像个小P孩,人年轻时总会心高气傲。有1 道面试题:给...

初雪之音 ⋅ 今天 ⋅ 0

Docker Toolbox Looks like something went wrong

Docker Toolbox 重新安装后提示错误:Looks like something went wrong in step ´Checking if machine default exists´ 控制面板-->程序与应用-->启用或关闭windows功能:找到Hyper-V,如果处......

随你疯 ⋅ 今天 ⋅ 0

Guacamole 远程桌面

本文将Apache的guacamole服务的部署和应用,http://guacamole.apache.org/doc/gug/ 该链接下有全部相关知识的英文文档,如果水平ok,可以去这里仔细查看。 一、简介 Apache Guacamole 是无客...

千里明月 ⋅ 今天 ⋅ 0

nagios 安装

Nagios简介:监控网络并排除网络故障的工具:nagios,Ntop,OpenVAS,OCS,OSSIM等开源监控工具。 可以实现对网络上的服务器进行全面的监控,包括服务(apache、mysql、ntp、ftp、disk、qmail和h...

寰宇01 ⋅ 今天 ⋅ 0

AngularDart注意事项

默认情况下创建Dart项目应出现以下列表: 有时会因为不知明的原因导致列表项缺失: 此时可以通过以下步骤解决: 1.创建项目涉及到的包:stagehand 2.执行pub global activate stagehand或pub...

scooplol ⋅ 今天 ⋅ 0

Java Web如何操作Cookie的添加修改和删除

创建Cookie对象 Cookie cookie = new Cookie("id", "1"); 修改Cookie值 cookie.setValue("2"); 设置Cookie有效期和删除Cookie cookie.setMaxAge(24*60*60); // Cookie有效时间 co......

二营长意大利炮 ⋅ 今天 ⋅ 0

【每天一个JQuery特效】淡入淡出显示或隐藏窗口

我是JQuery新手爱好者,有时间就练练代码,防止手生,争取每天一个JQuery练习,在这个博客记录下学习的笔记。 本特效主要采用fadeIn()和fadeOut()方法显示淡入淡出的显示效果显示或隐藏元...

Rhymo-Wu ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部