您的位置:首页 > 其它

mybatis调用存储过程

2017-11-16 14:52 429 查看
没有具体开发过mybatis调用存储过程,通过查看代码及资料,记录如下

注意:

1、在xml里 属性-statementType=”CALLABLE”

2、使用

CREATE OR REPLACE PROCEDURE "SP_MF_I_IMP"
( I_MANIFEST_I_ID    IN NUMBER ,
I_FUNCTION_CODE  IN VARCHAR2,
I_FIRM_ID        IN NUMBER,
I_OP_USER        IN VARCHAR2, --操作人ID
O_RETURN_MESSAGE OUT VARCHAR2  ) AS

--根据SEQ生成的报文头表的ID
V_HEAD_INFO_ID NUMBER(11);
--报文编号中,年月日时生成
V_YYMMDDHHMM VARCHAR2(10);
--报文编号
V_MESSAGE_ID VARCHAR2(50);
--申报人
V_SEND_ID VARCHAR2(50);
--货物运输批次号
V_TRAN_NO VARCHAR2(13);
--提运单号
V_BILL_NO VARCHAR2(35);
--异常报文
STR_L_ERRMSG VARCHAR2(3000);
--新增,修改,删除类型
V_FUNTYPE VARCHAR2(5);
--是否已经申报的标识
V_DECLARE VARCHAR(5);

BEGIN

--当要申报的单的状态为‘001’新单,‘008’发送海关失败时才需要发送
IF V_DECLARE = '001' OR V_DECLARE = '008' THEN
--获得SEQ_EDI_HEAD_INFO的值
SELECT EDI.SEQ_EDI_HEAD_INFO.NEXTVAL INTO V_HEAD_INFO_ID FROM DUAL;
--组装生成报文编号中的'YYMMDDHHMM'
SELECT TO_CHAR(SYSDATE,'YYMMDDHH24MI') INTO V_YYMMDDHHMM FROM DUAL;
--生成报文编号
V_MESSAGE_ID := '78921227X'|| V_YYMMDDHHMM || I_MANIFEST_I_ID;

--通过GET_SEND_ID函数获取SENDID
V_SEND_ID := GET_SEND_ID(I_FIRM_ID);

--新增报文头表信息
INSERT INTO EDI.EDI_MANIFEST_I_HEAD_INFO
(ID,MESSAGE_ID,FUNCTION_CODE,MESSAGE_TYPE,SENDER_ID,RECEIVER_ID,VERSION,IMP_ID)
VALUES
(V_HEAD_INFO_ID,V_MESSAGE_ID,I_FUNCTION_CODE,'MT1401',V_SEND_ID,'EPORT','1.0',I_MANIFEST_I_ID);

O_RETURN_MESSAGE := 'success';
--写入LOG表
SP_TRACE_WRITE(V_FUNTYPE, V_TRAN_NO, V_BILL_NO, I_OP_USER, '004', STR_L_ERRMSG, O_RETURN_MESSAGE);

END;
ELSE ---表示没有对应的申报类型,事物回滚,写入异常日志
O_RETURN_MESSAGE := 'error';
RAISE_APPLICATION_ERROR(-20100, 'Invalid Registration');
END IF;
COMMIT;

--异常处理
EXCEPTION
WHEN   OTHERS   THEN

STR_L_ERRMSG := SQLCODE || ' ' || SQLERRM;
ROLLBACK ;  --异常处理,异常点上面的操作都不会被执行

O_RETURN_MESSAGE := 'error';
SP_TRACE_WRITE(V_FUNTYPE, V_TRAN_NO, V_BILL_NO, I_OP_USER, '005', STR_L_ERRMSG, O_RETURN_MESSAGE);
COMMIT;
END SP_MF_I_IMP;


中间加入了异常处理,出现异常要回滚并且写入日志表,同时返回显示是否成功的标识。

如下是在mybatis配置如下:

<parameterMap id="sendMap" type="java.util.HashMap">
<parameter property="I_MANIFEST_I_ID" jdbcType="NUMERIC" javaType="java.lang.Long" mode="IN"/>
<parameter property="I_FUNCTION_CODE" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
<parameter property="I_FIRM_ID" jdbcType="NUMERIC" javaType="java.lang.Integer" mode="IN"/>
<parameter property="I_OP_USER" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN"/>
<parameter property="O_RETURN_MESSAGE" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT"/>
</parameterMap>

<update id="sendManifstmanToEdi" parameterMap="sendMap" statementType="CALLABLE">
<![CDATA[
{call SP_MF_I_IMP(?, ?, ?, ?, ?)}
]]>
</update>


存储过程中都有IN,OUT的参数,创建一个列出你要向存储过程传递的参数与获取的返回值。因为这边会有更新数据字段的设置,所以这边用的是,再在后台之后代码的设值、调用、获取返回值如下:

private String sendEdi(Long id) throws Exception {
String result = "";
Map<String,Object> params = new HashMap<String, Object>();
try {
params.put("I_MANIFEST_I_ID", id);
params.put("I_FUNCTION_CODE", Constants.MAINIFEST_DECLARE);
params.put("I_FIRM_ID", getFirmOfLoginUser().getFirmId());
params.put("I_OP_USER", getLoginUser().getLoginName());
params.put("O_RETURN_MESSAGE", "");
manifestIMainService.sendManifstmanToEdi(params);
result = String.valueOf(params.get("O_RETURN_MESSAGE"));
} catch (Exception e) {
log.error("sendEdi occurred error.", e);
if(Constants.IS_TEST)
setErrorMsg(e.getMessage());
}
return result;
}


二、返回SYS_REFCURSOR,我们取出将其对应成为一个List,写在里面,存储过程如下:

CREATE OR REPLACE PROCEDURE "SP_TRACE_GET"(I_DATA_TYPE IN CHAR,
I_TRAN_NO   IN VARCHAR2,
I_BILL_NO   IN VARCHAR2,
O_LIST      OUT SYS_REFCURSOR) AS
CURSOR_VALUE SYS_REFCURSOR;

BEGIN
CASE
WHEN I_DATA_TYPE = 'I' THEN
BEGIN
OPEN CURSOR_VALUE FOR
SELECT A.*
FROM MANIFEST_I_LOG A
WHERE A.TRAN_NO = I_TRAN_NO
AND A.BILL_NO = I_BILL_NO;
EXCEPTION
WHEN no_data_found THEN
RETURN;
END;
BEGIN
OPEN CURSOR_VALUE FOR
SELECT T.* FROM(
SELECT A.*
FROM MANIFEST_I_LOG A
WHERE A.TRAN_NO = I_TRAN_NO
AND A.BILL_NO = I_BILL_NO
UNION ALL
SELECT B.*
FROM BINDING_L_LOG B
WHERE B.TRAN_NO = I_TRAN_NO
UNION ALL
SELECT C.* FROM LOADCHANG_LOG C WHERE C.TRAN_NO = I_TRAN_NO)T ORDER BY T.OP_TIME DESC;
END;
WHEN I_DATA_TYPE = 'C' THEN
OPEN CURSOR_VALUE FOR
SELECT * FROM LOADCHANG_LOG WHERE TRAN_NO = I_TRAN_NO ORDER BY OP_TIME DESC;
END CASE;
O_LIST := CURSOR_VALUE;
END SP_TRACE_GET;


返回查询出来的结果,在mybatis的配置文件中可以跟上面一种不一样的方式来写,配置如下:

<!-- 结果集映射 -->
<resultMap id="flowLogsResultMap" type="com.hwt.glmf.log.vo.FlowLogModel">
<result column="ID" property="id" />
<result column="STATUS" property="status" />
<result column="OP_USER" property="op_user" />
<result column="OP_TIME" property="op_time" />
<result column="BILL_NO" property="bill_no" />
<result column="TRAN_NO" property="tran_no" />
<result column="MEMO" property="memo" />
<result column="DATA_TYPE" property="data_type" />
</resultMap>

<!-- jdbcType=INTEGER  ORACLE:INT-->
<select id="viewFlowLog" parameterType="java.util.Map" statementType="CALLABLE">
<![CDATA[
{call SP_TRACE_GET(#{I_DATA_TYPE,mode=IN,jdbcType=VARCHAR},
#{I_TRAN_NO,mode=IN,jdbcType=VARCHAR},#{I_BILL_NO,mode=IN,jdbcType=NUMERIC},
#{O_LIST,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=flowLogsResultMap})}
]]>
</select>


在后台代码如下

public List<FlowLogModel> viewFlowLog(String dataType, String tran_no,
String bill_no) throws Exception {
Map<String, Object> param = new HashMap<String, Object>();
param.put("I_DATA_TYPE", dataType);
param.put("I_TRAN_NO", tran_no);
param.put("I_BILL_NO", bill_no);
param.put("O_LIST", OracleTypes.CURSOR);
flowLogDao.viewFlowLog(param);
<
c65d
span class="hljs-constant">return (List<FlowLogModel>)param.get("O_LIST");
}


由此完成调用与取返回值,值得说的下的是在配置文件中配置时对应的

parameterType=”java.util.Map”

中的值全是java中具备的基础类型,而且根据字段的长度选择对应的类型。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mybatis