Java调用存储过程的几种情况

项目中用到了Java调用存储过程,趟过了几个坑,现分享一下常用的几种情形。下面的例子用的JdbcTemplate对持久层进行操作,有关JdbcTemplate的配置本文不再做详细说明,如不清楚,可参考本人另一篇博文SpringBoot使用JdbcTemplate多种方式介绍。

第一种情况:有普通返回值。

存储过程示例:

过程定义(获取学生信息):
PROCEDURE proc_get_student
(sno			in VARCHAR2 --学号
,name			in out VARCHAR2 --姓名
,age		    in out number --年龄
,classno	    in out VARCHAR2 --班级
);

实现代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.sql.*;

@Component
public class ProcedureDemo {

    @Autowired
    JdbcTemplate jdbcTemplate;

    public void queryStudentInfo() {
        jdbcTemplate.execute(
                new CallableStatementCreator() {
                    @Override
                    public CallableStatement createCallableStatement(Connection con) throws SQLException {
                        String storedProc = "{call comm.proc_get_student(?,?,?,?)}";// 调用的sql
                        CallableStatement cs = con.prepareCall(storedProc);
                        cs.setString(1, "001");//设置输入参数-学号
                        cs.registerOutParameter(2, Types.VARCHAR);//输出参数
                        cs.registerOutParameter(3, Types.INTEGER);
                        cs.registerOutParameter(4, Types.VARCHAR);
                        return cs;
                    }
                }, new CallableStatementCallback() {
                    @Override
                    public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
                        cs.execute();
                        String name = cs.getString(2);
                        int age = cs.getInt(3);
                        String classno = cs.getString(4);
                        return null;
                    }
                });
    }
}

 第二种情况:有数据集返回。

存储过程示例:

过程定义(获取一个班级学生信息):
PROCEDURE proc_get_students
(classno			in VARCHAR2 --班级
,classname			in out VARCHAR2 --班级名称
,cur_studentinfo	in out returncursor --学生信息结果集
);

实现代码:

import oracle.jdbc.OracleTypes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.sql.*;

@Component
public class ProcedureDemo {

    @Autowired
    JdbcTemplate jdbcTemplate;

    public void queryStudentInfos() {
        jdbcTemplate.execute(
                new CallableStatementCreator() {
                    @Override
                    public CallableStatement createCallableStatement(Connection con) throws SQLException {
                        String storedProc = "{call comm.proc_get_students(?,?,?)}";// 调用的sql
                        CallableStatement cs = con.prepareCall(storedProc);
                        cs.setString(1, "01");//班级号
                        cs.registerOutParameter(2, Types.VARCHAR);
                        cs.registerOutParameter(3, OracleTypes.CURSOR);//输出参数游标类型
                        return cs;
                    }
                }, new CallableStatementCallback() {
                    @Override
                    public Object doInCallableStatement(CallableStatement cs) throws SQLException,DataAccessException {
                        cs.execute();
                        System.out.println(cs.getString(2));
                        ResultSet rs = (ResultSet) cs.getObject(3);// 获取游标一行的值
                        while (rs.next()) {//打印每行的返回值
                            System.out.println(rs.getString("sno"));
                            System.out.println(rs.getString("name"));
                            System.out.println(rs.getInt("age"));
                        }
                        rs.close();
                        return null;
                    }
                });
    }
}

这种情况的难点在于输出参数为游标类型数据集,设置参数类型的时候为OracleTypes.CURSOR,依赖的jar包为ojdbc14-18.3.0.0.jar,对应的maven依赖:


            com.oracle
            ojdbc14
            18.3.0.0
        

第三种情况:输出参数为clob类型。

存储过程示例:

过程定义(获取学生成绩信息):
PROCEDURE proc_get_student_performance
(sno			in VARCHAR2 --学号
,student_return		in out clob --学生成绩报文,json字符串格式
);

实现代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.StringWriter;
import java.sql.*;

@Component
public class ProcedureDemo {

    @Autowired
    JdbcTemplate jdbcTemplate;

    public void queryStudentPerformance() {
        jdbcTemplate.execute(
                new CallableStatementCreator() {
                    @Override
                    public CallableStatement createCallableStatement(Connection con) throws SQLException {
                        String storedProc = "{call comm.proc_get_student_performance(?,?)}";// 调用的sql
                        CallableStatement cs = con.prepareCall(storedProc);
                        cs.setString(1, "001");
                        cs.registerOutParameter(2, Types.CLOB);//设置出参为clob类型
                        return cs;
                    }
                }, new CallableStatementCallback() {
                    @Override
                    public Object doInCallableStatement(CallableStatement cs) throws SQLException,DataAccessException {
                        cs.execute();
                        try {
                            Clob student_return = cs.getClob(2);
                            BufferedReader in = new BufferedReader(student_return.getCharacterStream());
                            StringWriter out = new StringWriter();
                            int c;
                            while ((c = in.read()) != -1) {
                                out.write(c);
                            }
                            String studentJsonStr = out.toString();//获取到json字符串,后面的解析省略
                            System.out.println(studentJsonStr);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                });
    }
}

第四种情况:输入参数为clob类型。

存储过程示例:

过程定义(保存学生成绩信息):
PROCEDURE proc_save_student_performance
(sno			in VARCHAR2 --学号
,student_save		in clob --学生成绩报文,json字符串格式
);

实现代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.sql.*;

@Component
public class ProcedureDemo {

    @Autowired
    JdbcTemplate jdbcTemplate;

    public void saveStudentPerformance(String performanceJsonStr) {
        jdbcTemplate.execute(
                new CallableStatementCreator() {
                    @Override
                    public CallableStatement createCallableStatement(Connection con) throws SQLException {
                        Clob performanceClob = new javax.sql.rowset.serial.SerialClob(performanceJsonStr.toCharArray());
                        String storedProc = "{call comm.proc_save_student_performance(?,?)}";// 调用的sql
                        CallableStatement cs = con.prepareCall(storedProc);
                        cs.setString(1, "001");
                        cs.setClob(2, performanceClob);
                        return cs;
                    }
                }, new CallableStatementCallback() {
                    @Override
                    public Object doInCallableStatement(CallableStatement cs) throws SQLException,DataAccessException {
                        cs.execute();
                        return null;
                    }
                });
    }
}

以上为常遇到的几种情况,不足之处敬请斧正。

 

 

 

 

 

你可能感兴趣的:(Spring,Boot,Jdbc,Template,java)