JAVA JDBC 调用存储过程 传参数

本文介绍了如何使用Java JDBC调用Oracle存储过程进行数据批量上传的优化,通过实例展示了无参数、带参数及处理list参数的存储过程调用,以及性能测试结果,证明了使用存储过程能有效提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

最近公司在做食堂POS机研发,有个功能是上传离线交易。每次向服务器提交1000~2000条数据,我们现在是循环将每一条save进去,现想优化下用存储过程来实现,减少jdbc连接。

1.准备

说明:我们数据库是:orcale 11g,java 是7

1.1 创建一张表

create table A
(
  aa VARCHAR2(30),
  b  VARCHAR2(30),
  c  VARCHAR2(40)
)

1.2 java创建一个类带main方法的类

/** 
 *
 *  @类功能说明  TODO
 *  @类修改者  
 *  @修改日期  
 *  @修改说明  
 *  @公司名称 Dlk
 *  @作者 樊强 
 *  @创建时间 2015年10月8日 上午11:28:34 
 *  @版本 V1.0 
 *
 */
public class JDBCProTest {
   public static void main(String[] args) {
<span style="white-space:pre">	</span>
   }
}
1.3 java 基本数据

	private static String X_DRIVER = "oracle.jdbc.driver.OracleDriver";
	private static String X_USERNAME = "bpim";
	private static String X_PASSWORD = "123456";
	private static String X_URL = "jdbc:oracle:thin:@192.168.1.25:1521:orcl";




2.直接在java程序里调用存储过程无参数无返回值。

2.1 存储过程

CREATE OR REPLACE PROCEDURE A_PROC
IS
BEGIN
 INSERT INTO A (aa)values('1');
  COMMIT;
END A_PROC;
2.2 java程序

/**
 * 
 *  @throws Exception
 *  @创建时间 2015年10月8日 上午11:35:03
 *  @作者  樊强
 *  @返回值 void
 *  @描述 测试调用存储过程:无返回值 无参数
 *
 */
    public static void testProcNoInNoOut() throws Exception {
        System.out.println("-------  start 测试调用存储过程:无返回值  无参数");
        Connection conn = null;
        CallableStatement callStmt = null;
        try {
            Class.forName(X_DRIVER);
            conn = DriverManager.getConnection(X_URL, X_USERNAME, X_PASSWORD);
            callStmt = conn.prepareCall("{call A_PROC()}");
            callStmt.execute();
            System.out.println("-------  测试调用存储过程:无返回值   无参数 End.");
        } catch (Exception e) {
            e.printStackTrace(System.out);
        } finally {
            if (null != callStmt) {
                callStmt.close();
            }
            if (null != conn) {
                conn.close();
            }
        }
    }

  public static void main(String[] args) {
    	try {
          testProcNoInNoOut();
        }catch (Exception e) {
		e.printStackTrace();
	}
}

          2.3 结果

 



3.直接在java程序里调用存储过程带参数无返回值。

     3.1 存储过程

CREATE OR REPLACE PROCEDURE AA_PROC(AA IN VARCHAR2) IS
BEGIN
 INSERT INTO A (aa)values(AA);
 COMMIT;
END AA_PROC;
3.2 java程序

 /**
     * 
     *
     *  @param String a
     *  @throws Exception
     *  @创建时间 2015年10月8日 下午2:07:48
     *  @作者  樊强
     *  @返回值 void
     *  @描述 测试调用存储过程:无返回值 有参数
     *
     */
    public static void testProc(String a) throws Exception {
        System.out.println("-------  start 测试调用存储过程:无返回值 有参数");
        Connection conn = null;
        CallableStatement callStmt = null;
        try {
            Class.forName(X_DRIVER);
            conn = DriverManager.getConnection(X_URL, X_USERNAME, X_PASSWORD);
            callStmt = conn.prepareCall("{call AA_PROC(?)}");
            callStmt.setString(1, a);
            callStmt.execute();
            System.out.println("-------  测试调用存储过程:无返回值 有参数 End.");
        } catch (Exception e) {
            e.printStackTrace(System.out);
        } finally {
            if (null != callStmt) {
                callStmt.close();
            }
            if (null != conn) {
                conn.close();
            }
        }
    }

   public static void main(String[] args) {
    	try {
                testProc("中文");
             } catch (Exception e) {
		e.printStackTrace();
             }
	}
3.3 结果

4.直接测试带循环的存储过程

  4.1 存储过程

CREATE OR REPLACE PROCEDURE AAA_PROC is
begin
  for i in 1 .. 5 loop
    insert into A (AA) values (i);
    commit;
  end loop;
end AAA_PROC;

    4.2 测试存储过程

begin
  aaa_proc;
end;

  4.3 结果



5.调用带list参数的存储过程

  带list参数的存储过程其实应该是array参数的存储过程,都是需要用list转化为array传到数据库中的。

 5.1 存储过程

create or replace type a_table is table of number;
create or replace type b_table is table of varchar2(30);
create or replace type c_table is table of varchar2(30);

在存储过程创建之前先声明这个array中的数据类型。(1 这里不是很确定)

CREATE OR REPLACE PROCEDURE AAAAA_PROC(
                       v_1 a_table,
                       v_2 b_table,
                       v_3 c_table)is
    v_count number;
begin
  v_count := v_1.count;
    for i in 1..v_count
       loop
           insert into A(AA, B, C)values(v_1(i),v_2(i), v_3(i));
           commit;
       end loop;
end AAAAA_PROC;

  5.2java程序调用

   /**
     * 
     *
     *  @param a
     *  @throws Exception
     *  @创建时间 2015年10月8日 下午2:07:48
     *  @作者  樊强
     *  @返回值 void
     *  @描述 测试调用存储过程:无返回值 有参数list 多字段
     *
     */
    public static void testProcList(List<Number> a1,List<String> a2,List<String> a3) throws Exception {
        System.out.println("-------  start 测试调用存储过程:无返回值 有参数list<span style="background-color: rgb(255, 255, 255); "> 多字段</span>");
        Connection conn = null;
        CallableStatement callStmt = null;
        try {
            Class.forName(X_DRIVER);
            conn = DriverManager.getConnection(X_URL, X_USERNAME, X_PASSWORD);
            callStmt = conn.prepareCall("{call AAAAA_PROC(?,?,?)}");
            ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("A_TABLE", conn); 
            ArrayDescriptor tabDesc1 = ArrayDescriptor.createDescriptor("B_TABLE", conn); 
            ArrayDescriptor tabDesc2 = ArrayDescriptor.createDescriptor("C_TABLE", conn); 
            ARRAY vArray1 = new ARRAY(tabDesc, conn, a1.toArray()); 
            ARRAY vArray2 = new ARRAY(tabDesc1, conn, a2.toArray()); 
            ARRAY vArray3 = new ARRAY(tabDesc2, conn, a3.toArray()); 
            callStmt.setArray(1, vArray1);
            callStmt.setArray(2, vArray2);
            callStmt.setArray(3, vArray3);
            callStmt.execute();
            System.out.println("-------  测试调用存储过程:无返回值 有参数list<span style="background-color: rgb(255, 255, 255); ">多字段 End.");</span>
        } catch (Exception e) {
            e.printStackTrace(System.out);
        } finally {
            if (null != callStmt) {
                callStmt.close();
            }
            if (null != conn) {
                conn.close();
            }
        }
    }
    public static void main(String[] args) {
    	try {
    		long aaaa=System.currentTimeMillis();
    		List<Number> a=new ArrayList<Number>();
    		List<String> b=new ArrayList<String>();
    		List<String> c=new ArrayList<String>();
    		a.add(1);
    		b.add("A"+1);
    		c.add("AA"+1);
    		testProcList(a,b,c);
    		long bbbb=System.currentTimeMillis();
    		System.out.println((bbbb-aaaa)/ 1000.00);
	<span style="white-space:pre">	</span>} catch (Exception e) {
			e.printStackTrace();
	<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>}

5.3 结果

          0.488秒



下面对这个调用过程做了个时间的验证

public static void main(String[] args) {
		try {
			long aaaa = System.currentTimeMillis();
			// testProcNoOut();
			// testProc("中文");
			List<Number> a = new ArrayList<Number>();
			List<String> b = new ArrayList<String>();
			List<String> c = new ArrayList<String>();
			for (int i = 0; i < 1000000; i++) {
				a.add(i);
				b.add("A" + i);
				c.add("AA" + i);
			 }
			testProcList(a, b, c);
			long bbbb = System.currentTimeMillis();
			System.out.println((bbbb - aaaa) / 1000.00);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


100条       0.592秒


1000条    0.604秒


10000条     1.306秒


100000条 8.663

1000000      85.3秒

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值