记两一下工作中用到的mybatis调用存储过程,这边用到的mybatis是3.2.2版本,oracle 10g。
一、返回一个值的存储过程,如下:
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配置如下:
private String sendEdi(Long id) throws Exception {
String result = "";
Map params = new HashMap();
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的配置文件中可以跟上面一种不一样的方式来写,配置如下:
在后台代码如下:
public List viewFlowLog(String dataType, String tran_no,
String bill_no) throws Exception {
Map param = new HashMap();
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);
return (List)param.get("O_LIST");
}
parameterType="java.util.Map"