mybatis调用存储过程

记两一下工作中用到的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配置如下:

  
	  
	  
	  
	
	  



	
  

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

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"

中的值全是java中具备的基础类型,而且根据字段的长度选择对应的类型。




你可能感兴趣的:(工作上的技术点)