使用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之间的映射关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值