使用iBatis調用存儲過程時的XML文件配置

iBatis(現在更名爲myBatis了)可以被看做是一個"半自動化"的ORM工具(通過sql-mapper),或者更嚴格的說,是一個關於JDBC API的強大封裝。簡單易學是它的優點,這也就是爲什麼在很多項目中,我都傾向於使用iBatis,尤其是提供大量複雜查詢或者報表功能的應用當中。

在<<iBatis in Action>>這本書中,講解了關於iBatis的各種用法,但是作者也特別強調了:在Dataaccess這層上,通過調用存儲過程是一個反模式,不推薦使用;於是關於通過iBatis調用存儲過程,只是非常簡單的一筆帶過。

但是我們也通常會在很多場合中,遇到要使用存儲過程的情況。就存儲過程本身,以Oracle存儲過程爲例,我們完全可以在一個jdbc事務裏面,完成有多個前後依賴步驟的較爲複雜的數據庫訪問,從而減少應用與數據庫之間的往返通訊。

在這裏,以Oracle數據庫爲例,講述通過iBatis調用Oracle存儲過程時的配置思路。在這裏我假定閱讀此文的人有關於iBatis的使用經驗,從而可以略過一些細節描述。

先看一下Oracle存儲過程接口:

PROCEDURE r_process_order(is_oid IN VARCHAR2, -- 訂單號
is_taskid in varchar2, --任務單號
is_price in number, --價格
is_gap in number, --浮動價差
is_notes in varchar2, --備註
is_timelimit in number, --報價有效時間限制
is_userid in varchar2, -- 用戶編號
is_deptid in varchar2, -- 用戶所在部門id

oi_flag OUT INTEGER, --0 成功 -1 錯誤
os_msg OUT VARCHAR2, --出錯信息
os_finish out varchar2, --是否完成訂單流程 0否 1是
or_order_item_list out sys_refcursor, -- 訂單條目信息
or_task_item_list out sys_refcursor, -- 後續待辦事項信息
or_userlist out sys_refcursor -- 廣播通知的用戶集
);


對應地,在ibatis的xml配置文件中,針對該存儲過程調用的配置如下所述:

<!-- 訂單:應答 -->
<parameterMap id="map_r_process_order" class="doRfqReply">
<parameter property="orderId" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" />
<parameter property="taskId" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" />
<parameter property="price" jdbcType="DOUBLE" javaType="java.math.BigDecimal" mode="IN" />
<parameter property="gap" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" />
<parameter property="notes" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" />
<parameter property="userId" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" />
<parameter property="deptId" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" />

<parameter property="flag" jdbcType="INTEGER" javaType="int" mode="OUT" />
<parameter property="msg" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT" />
<parameter property="strFinish" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT" />
<parameter property="orderItemList" jdbcType="ORACLECURSOR" javaType="java.sql.ResultSet" mode="OUT"

resultMap="orderItemListResult" />
<parameter property="taskItemList" jdbcType="ORACLECURSOR" javaType="java.sql.ResultSet" mode="OUT"

resultMap="taskItemListResult" />
<parameter property="processUserIds" jdbcType="ORACLECURSOR" javaType="java.sql.ResultSet" mode="OUT"

resultMap="processUserId" />
</parameterMap>
<procedure id="r_process_order" parameterMap="map_r_rfq_reply">
{ call p_foo_bar_manager.r_process_order(?,?,?,?,?,?,?,?,?,?,?,?,?)}
</procedure>


上面這段代碼包含了兩點,id爲“map_r_process_order”聲明瞭傳入參數和Oracle存儲過程接口參數之間的映射關係,按照順序對應;
id爲"r_process_order"執行存儲過程調用。存儲過程的IN參數類型和OUT參數類型,總數爲13個,所以?號個數也是13,順序對應。

Java代碼在此處從略:基本上,較爲簡單的做法,就是針對IN和OUT類型,準備兩個VO對象,分別包裝存儲過程的傳入參數和傳出參數。

傳入參數屬性結構較爲簡單。

傳出參數,既包括基本類型例如flag(integer),msg(String),也包括了複合類型。在這裏orderItemList表示我們期望存儲過程以遊標返回一個 List<OrderItem>結果集,指定jdbcType爲ORACLECURSOR,iBatis會自動幫助我們完成ResultSet與POJO的數據綁定(這裏的POJO是 OrderItem)。當然,在這裏我們需要提供一個resultMap,來描述遊標行集中的每一個行,與我們的OrderItem之間的映射關係。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章