Mybaits结合Oracle调用存储过程返回游标的两种方法

时间:2022-03-29 15:51:04

首先你得有张测试表,无论什么表有一两个数据就可以,我本身了解的也不多,所以本文旨在用最简单最明了的方式来介绍Mybaits结合Oracle调用存储过程返回游标结果集,帮助和我一样新入门的同学,高手欢迎指出错误帮助我们成长。

然后你得了解Oracle游标的概念及作用,你有没有试过在用mybaits想查询很多行数据但对每行的数据做不同的业务处理呢?那么还有一个问题是如果存储过程让你返回一个结果集但存储过程没有java的list又该怎么办?那么我们的游标就闪亮登场了,来一段关于游标的官方解释:游标是 SQL 的一个内存工作区,由系统或用户以变量的形式定义。游标的作用就是用于临时存储从数据库中提取的数据块。在某些情况下,需要把数据从存放在磁盘的表
中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库。这样数据
处理的速度才会提高,否则频繁的磁盘数据交换会降低效率。
游标有两种类型:显式游标和隐式游标,在前述程序中用到的 SELECT…INTO…查询
语句,一次只能从数据库中提取一行数据,对于这种形式的查询和 DML 操作,系统都会
使用一个隐式游标。但是如果要提取多行数据,就要由程序员定义一个显式游标,并通
过与游标有关的语句进行处理。显式游标对应一个返回结果为多行多列的 SELECT 语句。
游标一旦打开,数据就从数据库中传送到游标变量中,然后应用程序再从游标变量
中分解出需要的数据,并进行处理。

然后我们就开始建立带游标的存储过程,创建带游标的存储过程有两种方式,一种是声明系统游标,一种是声明自定义游标,然后后面操作一样,参数类型为 in out 或out ,系统游标就是不用定义包头包体,而自定义游标就需要了,当然自定义游标也灵活些,我在网上搜索相关学习资料时,总是看见一些文章对别人的引用丢三落四,定义包头没有包体,自己建系统游标介绍的又不清楚,各种关键字的错误导致我走了一点弯路,就在这里吐个槽吧。
先来建立系统游标:

CREATE OR REPLACE Procedure test_speed(p_cursor out Sys_Refcursor)--这就是test_speed的存储过程输出参数为p_cursor的一个游标
As
begin
open p_cursor for Select * From t_test;
--将查询到的数据放到游标中
End;

再来看自定义游标如何创建:首先定义一个包头:

CREATE OR REPLACE PACKAGE PAK_TEST
IS
TYPE retcursor IS REF CURSOR;
PROCEDURE test_speed
(
p_cursor IN OUT retcursor
)
;
--声明包体的存储过程
END;

包体:

CREATE OR REPLACE PACKAGE BODY PAK_TEST IS
PROCEDURE test_speed
(
p_cursor IN OUT retcursor
)--该存储过程已在包头中声明,我在网上看到有的用 p_cursor IN OUT PAK_TEST.retcursor的方式来声明,反正我在测试中会报错
IS
begin
OPEN p_cursor FOR
select * from t_test;
--将查询到的数据放到游标中
end;
END;

–记得重用代码时去掉汉字,游标和存储过程都要end
好,存储过程已经用两种方式都建立好了,然后用mybaits来调用,我前面写过mybaits的配置及动态成表curd数据库,请参考http://blog.csdn.net/sureSand/article/details/52540684
只需要在BasicMapper.xml中添加一个select操作,然后模仿insert和update调用test_speed即可:

<resultMap type ="java.util.HashMap" id= "cursorMap"> 
<result column ="id" property="id"/>
<result column ="name" property="name"/>
</resultMap >
<select id="test_speed" parameterType="java.util.Map" statementType="CALLABLE" >
{call PAK_rstest.pro_read (#{p_cursor, mode=OUT, jdbcType=CURSOR, resultMap=cursorMap})}
</select>