1. 程式人生 > >Mybaits結合Oracle呼叫儲存過程返回遊標的兩種方法

Mybaits結合Oracle呼叫儲存過程返回遊標的兩種方法

首先你得有張測試表,無論什麼表有一兩個資料就可以,我本身瞭解的也不多,所以本文旨在用最簡單最明瞭的方式來介紹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>