首页 > 其他分享 >JdbcTemplate中如何进行存储过程调用

JdbcTemplate中如何进行存储过程调用

时间:2023-11-16 19:00:43浏览次数:25  
标签:存储 调用 String JdbcTemplate cs new public jdbcTemplate

JdbcTemplate调用存储过程的主要有三种方发(精)

一、jdbcTemplate.call()

定义如下:

Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters) throws DataAccessException;

第一个参数是创建调用存储过程的方法的参数,第二个参数是返回结果的Map接收集合;

JdbcTemplate中如何进行存储过程调用_存储过程

public void test002() {
        //定义参数
        List<SqlParameter> params = new ArrayList<SqlParameter>();
        params.add(new SqlOutParameter("result", Types.INTEGER));
        params.add(new SqlParameter("str", Types.VARCHAR));
        jdbcTemplate.call(new CallableStatementCreator() {
            @Override
            public CallableStatement createCallableStatement(Connection con) throws SQLException {
                String storedProc = "{call sp_list_table(?,?)}"; //调用的SQL
                CallableStatement callableStatement = con.prepareCall(storedProc);
                return callableStatement;
            }
        }, params);
    }


二、jdbcTemplate.execute()

定义如下:

<T> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action) throws DataAccessException;

参数为一个存储过程语句生成和调用存储过程中返回的回调函数。

public void test001() {
        jdbcTemplate.execute(
                new CallableStatementCreator() {
                    @Override
                    public CallableStatement createCallableStatement(Connection con) throws SQLException {
                        String storedProc = "{call sp_list_table(?,?)}"; //调用的SQL
                        CallableStatement callableStatement = con.prepareCall(storedProc);
                        callableStatement.setString(1, "p1"); //设置输入参数的值
                        callableStatement.registerOutParameter(2, MysqlType.FIELD_TYPE_VAR_STRING); //注册输出参数的类型
                        //callableStatement.registerOutParameter(2, OracleTypes.CURSOR); //注册输出参数的类型,oracle的游标,下面可以取值
                        return callableStatement;
                    }
                }, new CallableStatementCallback<Object>() {
                    @Override
                    public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
                        List resultsMap = new ArrayList();
                        cs.execute();
                        String name = cs.getString(2);
                        return name;
//                        ResultSet rs = (ResultSet) cs.getObject(2); //获取游标一行的值
//                        while (rs.next()) { //转换每行的返回值到Map中
//                            Map rowMap = new HashMap();
//                            rowMap.put("id", rs.getString("id"));
//                            rowMap.put("name", rs.getString("name"));
//                            resultsMap.add(rowMap);
//                        }
//                        rs.close();
//                        return resultsMap;
                    }
                }
        );
    }


三、jdbcTemplate.execute()2

定义如下:

<T> T execute(String callString, CallableStatementCallback<T> action) throws DataAccessException;

参数一个调用存储过程的SQL语句,一个是调用存储过程中返回的回调函数;

public void test003() {
        /**代码片段*/
        //5个输入参数,3个输出参数
        String sql = "{call GENERATEORDERS_P(?,?,?,?,?,?,?,?)}";

        // 这里的result是指从其他查询获取来的结果,从结果中拿到值,以他为参数再到这次存储过程中获取东西
        final String company_id = result.get("F_COMPANY_ID").toString();           // 公司ID
        final String competition_id = result.get("F_COMPETITION_ID").toString();   // 比赛ID
        final String current_phase = result.get("F_CURRENT_PHASE").toString();     // 当前周期
        final String market_scope_id = result.get("F_MARKET_SCOPE_ID").toString(); // 市场ID
        final String market_loca_id = result.get("F_MARKET_LOCA_ID").toString();   // 产品类型ID

        Map mapR = (Map) jdbcTemplate.execute(sql, new CallableStatementCallback<Object>() {
            @Override
            public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
                cs.setString(1, current_phase);    // 输入参数
                cs.setString(2, competition_id);   // 输入参数
                cs.setString(3, market_scope_id);  // 输入参数
                cs.setString(4, market_loca_id);   // 输入参数
                cs.setString(5, company_id);       // 输入参数
                cs.registerOutParameter(6,Types.VARCHAR);//输出参数
                cs.registerOutParameter(7,Types.VARCHAR);//输出参数
                cs.registerOutParameter(8,Types.VARCHAR);//输出参数
                cs.execute();
                Map map = new HashMap();
                map.put("RESULT", cs.getString(6));       // 订单数量
                map.put("F_PRICE", cs.getString(7));      // 订单价格
                map.put("F_CPUT_MOD_ID", cs.getString(8));// 产品型号ID
                return map;
            }
        });

    }

jdbctemplate 调用存储过程

项目需要使用原生态的 jdbc 调用存储过程,写法如下,备忘一下

首先声明一个存储过程

CREATE DEFINER = `root`@`localhost` PROCEDURE `P_SVNTASKADD`(in par1 varchar(1000),in par2 varchar(100),in par3 varchar(200),in par4 varchar(200),in par5 varchar(100),in par6 varchar(2500),out parout int)
begin
insert into svnTask  (svnUrl,svnType,developer,dba,createTime,modifyTime,filesNum,filesString,state) values(par1,par2,par3,par4,now(),now(),par5,par6,0);
select MAX(taskId) into parout from svntask;
end;

接下来在 java 中使用如下代码调用:

String sql = "{call P_SVNTASKADD(?,?,?,?,?,?,?)}";
Object obj = jdbcTemplate.execute(sql,new CallableStatementCallback(){
        public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException { 
            cs.setString(1,(String) argsForNewTask[0]); 
            cs.setString(2,(String) argsForNewTask[1]); 
            cs.setString(3,(String) argsForNewTask[2]); 
            cs.setString(4,(String) argsForNewTask[3]); 
            cs.setString(5,(String) argsForNewTask[4]); 
            cs.setString(6,(String) argsForNewTask[5]); 
            cs.registerOutParameter("parout", Types.INTEGER); 
            cs.execute(); 
            return new Integer(cs.getInt("parout")); 
        }
    }); 
int taskIdResult=((Integer)obj).intValue();

转自:https://my.oschina.net/zimingforever/blog/138237/



JdbcTemplate中如何进行存储过程调用

JdbcTemplate可以通过调用CallableStatement来执行存储过程。主要步骤如下:

定义存储过程:

CREATE PROCEDURE get_user(IN id INT, OUT name VARCHAR(50))
BEGIN
    SELECT name INTO name FROM user WHERE id = id;
END

构造调用语句:

CALL get_user(?, ?)

定义CallableStatementCreator接口实现,用于构造调用语句:

CallableStatementCreator csc = new CallableStatementCreator() {
    public CallableStatement createCallableStatement(Connection conn) throws SQLException {
        return conn.prepareCall("{CALL get_user(?, ?)}");
    }
};

执行存储过程并提取OUT参数:

final String[] name = new String[1];
jdbcTemplate.call(csc, new CallableStatementCallback<Void>() {
    public Void doInCallableStatement(CallableStatement cs) throws SQLException {
        cs.setInt(1, 1);
        cs.registerOutParameter(2, Types.VARCHAR);
        cs.execute();
        name[0] = cs.getString(2);
        return null;
    }
});
System.out.println(name[0]); // John
  • 传入CallableStatementCreator实现构造调用语句
  • 实现CallableStatementCallback接口,在回调方法中设置IN参数,注册OUT参数,执行调用并提取OUT参数
  • OUT参数通过数组传入,回调后得到输出值

所以,通过JdbcTemplate调用存储过程主要需要完成3个步骤:

  1. 构造存储过程调用语句
  2. 实现CallableStatementCreator构造CallableStatement
  3. 实现CallableStatementCallback设置参数、执行调用和获取输出

JdbcTemplate通过这种方式,简化了存储过程的调用,隐藏了JDBC底层细节,提供了更易用的接口。



JdbcTemplate调用Oracle存储过程的一些方法

1、 无返回值的存储过程调用:

public class JdbcTemplateTest { 
   private JdbcTemplate jdbcTemplate; 
   public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { 
   this.jdbcTemplate = jdbcTemplate; 
   } 
   public void test(){ 
      this.jdbcTemplate.execute("call testpro('p1','p2')"); 
   } 
 }

2、有返回值的存储过程(非结果集)

public void test() { 
   String param2Value = (String) jdbcTemplate.execute( 
      new CallableStatementCreator() { 
         public CallableStatement createCallableStatement(Connection con) throws SQLException { 
            String storedProc = "{call testpro(?,?)}";// 调用的sql 
            CallableStatement cs = con.prepareCall(storedProc); 
            cs.setString(1, "p1");// 设置输入参数的值 
            cs.registerOutParameter(2, OracleTypes.VARCHAR);// 注册输出参数的类型 
            return cs; 
         } 
      }, new CallableStatementCallback() { 
          public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException { 
            cs.execute(); 
            return cs.getString(2);// 获取输出参数的值 
      } 
   }); 
 }

3、有返回值的存储过程(结果集)

1.建一个程序包,如下: 
CREATE OR REPLACE PACKAGE TESTPACKAGE AS 
  TYPE TEST_CURSOR IS REF CURSOR; 
END TESTPACKAGE; 
2.建立存储过程,如下: 
CREATE OR REPLACE PROCEDURE TESTPRO(PARAM1 IN VARCHAR2,test_cursor out TESTPACKAGE.TEST_CURSOR) IS 
BEGIN 
     OPEN test_cursor FOR SELECT * FROM TESTTABLE; 
END TESTPRO; 
可以看到,列表是通过把游标作为一个out参数来返回的。

java测试代码:

public void test() { 
   List resultList = (List) jdbcTemplate.execute( 
      new CallableStatementCreator() { 
         public CallableStatement createCallableStatement(Connection con) throws SQLException { 
            String storedProc = "{call testpro(?,?)}";// 调用的sql 
            CallableStatement cs = con.prepareCall(storedProc); 
            cs.setString(1, "p1");// 设置输入参数的值 
            cs.registerOutParameter(2, OracleTypes.CURSOR);// 注册输出参数的类型 
            return cs; 
         } 
      }, new CallableStatementCallback() { 
         public Object doInCallableStatement(CallableStatement cs) throws SQLException,DataAccessException { 
            List resultsMap = new ArrayList(); 
            cs.execute(); 
            ResultSet rs = (ResultSet) cs.getObject(2);// 获取游标一行的值 
            while (rs.next()) {// 转换每行的返回值到Map中 
               Map rowMap = new HashMap(); 
               rowMap.put("id", rs.getString("id")); 
               rowMap.put("name", rs.getString("name")); 
               resultsMap.add(rowMap); 
            } 
            rs.close(); 
            return resultsMap; 
         } 
   }); 
   for (int i = 0; i < resultList.size(); i++) { 
      Map rowMap = (Map) resultList.get(i); 
      String id = rowMap.get("id").toString(); 
      String name = rowMap.get("name").toString(); 
      System.out.println("id=" + id + ";name=" + name); 
   } 
 }


在Spring JdbcTemplate中使用call调用存储的函数

本文介绍了在Spring JdbcTemplate中使用call调用存储的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

    CREATE OR REPLACE PACKAGE BODY pk_sahil AS  
      procedure squareNumDummy(x in number,y in number) is
      begin
        dbms_output.put_line(x*y);
        insert into sahil values('package',111);
      end squareNumDummy;
      function sumFun( x in number , y in number ) return number is
      begin
        insert into sahil values('function',222);
        return x+y;
      end sumFun;
    END pk_sahil; 
    /
    create or replace package pk_sahil as
      procedure squareNumDummy(x in number, y in number);
      function sumFun(x in number, y in number ) return number;
    end pk_sahil;
    /

我已经用一个函数和一个过程制作了这个程序包,我正在尝试使用spring jdbctemplate从我的Java代码中调用它们.但是过程运行正常,但无法调用此函数.

int param1 =5 , param2 = 10;
jdbcTemplate.update( "call pk_sahil.squareNumDummy(?,?)",param1,param2);

此过程运行正常.

jdbcTemplate.update( "call pk_sahil.sumFun(?,?)",param1,param2);

运行此功能后,我将遇到错误

纠正我是否不是以正确的方式调用该函数,还是需要处理函数的返回变量?如何从jdbctemplate.update('call ...')方法调用该函数?

推荐答案

您可以从jdbcTemplate.queryForObject()调用存储的函数,如下所示:

int sum = jdbcTemplate.queryForObject("SELECT pk_sahil.squareNumDummy(?,?)", new Object[] {param1,param2});


标签:存储,调用,String,JdbcTemplate,cs,new,public,jdbcTemplate
From: https://blog.51cto.com/lenglingx/8431270

相关文章

  • C++调用Python3实战,和PyImport_ImportModule返回NULL问题解决
    LinuxC++调用Python3入门准备以下面的目录结构演示如何在LinuxC/C++调用python3。|--hello.py|--main.cpp|--CMakeLists.txt hello.py:python的脚本,里面有2个函数main.cpp:c++函数CMakeLists.txt:Cmake文件,生成makefilepython脚本示例python脚本hello.py内容如下,......
  • 基于pybind11实现C++程序中调用Python脚本增加C++程序扩展性
     文章目录前言一、pybind11与Python环境配置二、C++环境配置三、C++调用Python交互代码四、C++调用PythonDemo完整源码 前言Windows平台,在实际C++项目开发中,结合pybind11库,让python成为C++的脚本语言,可以大大提高C++程序的可扩展性,大大提高开发效率,特别......
  • C++通过pybind11调用Python 实现transpose
    在某些场合需要在C++实现类似numpy的numpy.transpose(a,axes)功能,但是很多库如NumCpp都没有提供这样的方法,只有二维矩阵的转置,没法进行多维矩阵任意维度的转换。比较简单的想法就是利用numpy现有的功能,在c++代码里面通过调用python来调用Numpy的transpose。直接调用Python提......
  • C++调用python踩坑记录
     目录0、参考文档及博客1、环境配置步骤2、C++调用python的方法代码框架:(同样来源于上面这篇博客,可用于测试环境配置成功与否)报错处理函数(1)处理方法一:PyErr_Print(2)处理方法二:PyErr_Fetch2.5、终极解决方案3、踩坑记录(1)python第三方库调用出错(2)python模块环......
  • 微服务 在 Java 代码中发送 http 请求(跨服务远程调用)
    1.注册RestTemplate对象到Spring容器中(Bean的注入只能放在配置类里,而启动类本身就是配置类)@SpringBootApplicationpublicclassOrderServiceApplication{publicstaticvoidmain(String[]args){SpringApplication.run(OrderServiceApplication.class,......
  • C#调用C++动态库接口函数和回调函数方法 后续
    声明回调委托,C#的委托可以实现C#调用C++的回调,操作函数以后的回调//定义委托,CallingConvention.StdCall可以,CallingConvention.Cdecl不行,参考https://www.it1352.com/1792610.html//[UnmanagedFunctionPointer(CallingConvention.Cdecl)]//不需要要添加该句话,具体参考//htt......
  • SAP ABAP调用REST服务
    就是调用为外部HTTP接口 zcl_json=>deserialize因为版本问题 自定义的json转换函数 根据自己的版本使用对应函数就好reportztest25.data:urltypestring,"接口地址gv_json_intypestring,"输入参数(账号密码啥的)jso......
  • python调用ffmpeg循环播放一个文件夹内的视频,如果播放中断了,下次继续播放可以从上次播
    importosimportsubprocessdefplay_videos_in_folder(folder_path):#获取所有视频文件files=[os.path.join(folder_path,f)forfinos.listdir(folder_path)iff.endswith(('.mp4','.mkv'))]idx=0#视频文件索引whileTrue:......
  • SAP调用外部的REST服务 http_communication_failure Connection to partner timed
    SAP中主动调用外部的REST服务时候, 因为传输的数据量比较大, 所以报Connectiontopartnertimedoutafter60 这一错误,原因之一可能是Tcode-SMICM ->转到->服务设置保活和处理超时时间,秒为单位,可以更具自己的需求进行设置。......
  • C#调用C++动态库接口函数和回调函数方法
    这篇文章主要介绍了C#调用C++动态库接口函数和回调函数方法,通过C++端编写接口展开内容,文章介绍详细具有一定的参考价值,需要的小伙伴可以参考一下需求: 当前C已经写好了一个动态库,完成了产品开发需求,C#需要调用C编写的动态库DLL接口,开发出完整的软件,DLL动态库里包含了普通接口函......