Mybatis Plus 调用Oracle存储 返回索引 Cursor

Mybatis Plus 调用Oracle存储 返回索引 Cursor

什么要写这篇博客

mybatis 调用oracle 存储过程,返回一个表。这样的景场用得比较少,我用了mybatis这么长时间,还第一次这么用。
尝试过程也是比较痛苦,网上资料少不说,很多配置拿下来,也是跑不起来。。最后自己不停地跟据mybatis抛出来的错误,调整代码,终于跑起来了。做一下笔记。

存储过程

存储过程比较长,只需要关注输入,输出参数就可以了。

CREATE OR REPLACE PROCEDURE P_QMS_GET_MIS_RPT(MIS_TYPE        VARCHAR2, --1:3MIS 2:6MIS
                                              MIS_DATE          VARCHAR2, --时间条件
                                              OTHER_CONDITION VARCHAR2, --其它条件
                                              DATE_TYPE       NVARCHAR2, -- 1:年 2:月  3:周
                                              GROUP_BY        VARCHAR2, --维度 BRAND
                                              P_CUR           OUT SYS_REFCURSOR
                                              ) AS
                                              
  V_SQL        VARCHAR2(4000);
  V_CON   VARCHAR2(500):='';
  V_DATE DATE;
  V_STRAT_DATE date;
  V_END_DATE   date;
  V_MIS_MONTH  varchar2(50);
  V_START_DATE_STR VARCHAR2(100);
  V_END_DATE_STR VARCHAR2(100);
BEGIN

V_DATE:=TO_DATE(MIS_DATE,'yyyy-MM-dd');
  V_STRAT_DATE := Trunc(add_months(V_DATE, -3 * MIS_TYPE ), 'mm');
  V_END_DATE   := Last_Day(add_months(V_DATE, -1));
  V_MIS_MONTH  := to_char(Trunc(add_months(V_DATE, -1), 'mm'), 'yyyymm');
  
  V_START_DATE_STR:= ' to_date('''|| to_char( V_STRAT_DATE,'yyyy-MM-dd') ||''',''yyyy-MM-dd'') ';
  V_END_DATE_STR := ' to_date('''|| to_char( V_END_DATE,'yyyy-MM-dd') ||''',''yyyy-MM-dd'') ';
  
  V_CON:=V_CON || ' and ACTIVE_START>=  ' || V_START_DATE_STR ;
  V_CON:=V_CON || '  and ACTIVE_START < '|| V_END_DATE_STR || '+1';
  V_CON:=V_CON|| ' ';

   V_SQL := ' with B as --市场不良数
   (SELECT '|| GROUP_BY ||', sum(QTY) AS sc_qty
      FROM T_QMS_DB_COMMON_CACULATE cc
     where cc.CACULATE_TYPE = ''10''
       '|| V_CON ||'
     group by '|| GROUP_BY ||'),
  --销售数量
  C as
   (SELECT '|| GROUP_BY ||', sum(QTY) AS s_qty
      FROM T_QMS_DB_COMMON_CACULATE cc
     where cc.CACULATE_TYPE = ''40''
       '|| V_CON ||'
     group by '|| GROUP_BY ||' ),
  --生产数量
  D as
   (SELECT '|| GROUP_BY ||', sum(QTY) AS pro_qty
      FROM T_QMS_DB_COMMON_CACULATE cc
     where cc.CACULATE_TYPE = ''30''
         '|| V_CON ||'
     group by '|| GROUP_BY ||' ),
  --销售比率
  E as
   (select d.'|| GROUP_BY ||',
           round(least(sum(c.s_qty) / sum(d.pro_qty), 1), 8) as rate,
           sum(c.s_qty) sale_qty,
           sum(d.pro_qty) pro_qty
      from D, c
     where 1 = 1 and
        d.'|| GROUP_BY ||' = c.'|| GROUP_BY ||'
     group by d.'|| GROUP_BY ||'),
  --交货数量
  F as
   (SELECT '|| GROUP_BY ||', sum(QTY) AS part_qty
      FROM T_QMS_DB_COMMON_CACULATE cc
     where cc.CACULATE_TYPE = ''20''
         '|| V_CON ||'
     group by '|| GROUP_BY ||' ),
  --交货数量*销售比率获取 =索赔零件总数
  G as
   (select F.BRAND, sum(F.part_qty * E.rate) as instrorage_qty
      from F, E
     where F.'|| GROUP_BY ||' = E.'|| GROUP_BY ||'
     group by F.'|| GROUP_BY ||'),
  --计算实绩值
  H AS
   (select G.'|| GROUP_BY ||',
           B.sc_qty,
           instrorage_qty,
           round(B.sc_qty / instrorage_qty * 1000000, 1) as rate,
           round(B.sc_qty / instrorage_qty * 1000000, 10) rate_dec
      from G
      left join B
        on G.'|| GROUP_BY ||' = B.'|| GROUP_BY ||'),
    V AS
   (SELECT TARGET_VAL, BRAND AS TARGET_TYPE_NAME
      FROM T_QMS_DB_TARGET_VAL T
     WHERE
         T.BUSI_TYPE = ''10''
       AND T.TARGET_DATE= '''||V_MIS_MONTH||''')
  
  SELECT 
         '|| GROUP_BY ||' as SUMARY_NAME,
         rate_dec,
         '''||V_MIS_MONTH||''' as MIS_DATE,
         nvl((select target_val from V where H.'|| GROUP_BY ||' = V.target_type_name and rownum=1), 0) as target_val
         
    FROM H';
  OPEN P_CUR FOR V_SQL;
END;

Mapper.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xx.xx.xx.reportstatic.idal.mapper.MisRptMapper">
    <resultMap  id= "misPrcInputResult" type ="com.ly.mp.qms.reportstatic.entities.MisPrcInputResult" >
        <result column ="sumary_name" property="sumaryName" jdbcType="VARCHAR"  />
        <result column ="rate" property="rate"   jdbcType="VARCHAR" />
        <result column ="mis_date" property="misDate" jdbcType="VARCHAR"  />
        <result column ="target_val" property="targetVal"  jdbcType="VARCHAR" />
    </resultMap >

    <select id="getMisRpt" statementType="CALLABLE" >
        {call p_qms_get_mis_rpt
            (
                #{misType,mode=IN,jdbcType=VARCHAR}, <!--注意要使用置jdbcType -->
                #{misDate,mode=IN,jdbcType=VARCHAR},
                #{otherCondition,mode=IN,jdbcType=VARCHAR},
                #{dateType,mode=IN,jdbcType=VARCHAR},
                #{groupBy,mode=IN,jdbcType=VARCHAR},
                #{result,mode=OUT,jdbcType=CURSOR, javaType=ResultSet,resultMap=misPrcInputResult}
            )}
    </select>
</mapper>

这里主要注意
1:输入参数的格式为 #{misType,mode=IN,jdbcType=VARCHAR},需要设参数名称(misType),参数类型 (mode=IN),参数数据类型(jdbcType=VARCHAR)为字符,网上找的资料都是没有设置 jdbcType=VARCHAR,但我的环境跑不起来。
2:输出参数设置, #{result,mode=OUT,jdbcType=CURSOR, javaType=ResultSet,resultMap=misPrcInputResult。名称(result),参数类型为输出(mode=OUT),参数数据类型(jdbcType=CURSOR)为索引。
输出的参数还需要另外设置javaType和resultMap。javaType=ResultSet 表示对应的java类型是一个列表,对应List;resultMap=misPrcInputResult 表示集合字段对应的印身是 misPrcInputResult。

Entity

  public   class  MisPrcInputResult  implements  java.io.Serializable
    {
         private String sumaryName;
         private  String rate;
         private  String misDate;
         private  String targetVal;

        public String getSumaryName() {
            return sumaryName;
        }

        public void setSumaryName(String sumaryName) {
            this.sumaryName = sumaryName;
        }

        public String getRate() {
            return rate;
        }

        public void setRate(String rate) {
            this.rate = rate;
        }

        public String getMisDate() {
            return misDate;
        }

        public void setMisDate(String misDate) {
            this.misDate = misDate;
        }

        public String getTargetVal() {
            return targetVal;
        }

        public void setTargetVal(String targetVal) {
            this.targetVal = targetVal;
        }
    }
import java.sql.Date;
import java.util.List;
public class MisPrcInput implements java.io.Serializable {
    private String misType;
    private String misDate;
    private String otherCondition;
    private String dateType;
    private String groupBy;
    private List<MisPrcInputResult> result;
    
    public String getMisType() {
        return misType;
    }
    public void setMisType(String misType) {
        this.misType = misType;
    }
    public String getMisDate() {
        return misDate;
    }
    public void setMisDate(String misDate) {
        this.misDate = misDate;
    }
    public String getOtherCondition() {
        return otherCondition;
    }
    public void setOtherCondition(String otherCondition) {
        this.otherCondition = otherCondition;
    }
    public String getDateType() {
        return dateType;
    }
    public void setDateType(String dateType) {
        this.dateType = dateType;
    }
    public String getGroupBy() {
        return groupBy;
    }
    public void setGroupBy(String groupBy) {
        this.groupBy = groupBy;
    }
    public List<MisPrcInputResult> getResult() {
        return result;
    }
    public void setResult(List<MisPrcInputResult> result) {
        this.result = result;
    }
}

Mapper.java

public interface MisRptMapper extends BaseMapper<MisCaculate> {

    public void  getMisRpt(MisPrcInput inp );
}

Biz

    @Autowired
    MisRptMapper misRptMapper;

    @Override   
    public RestResult<List<MisPrcInputResult>> getMisPrc() throws ParseException {
        MisPrcInput inp= new MisPrcInput();
        inp.setDateType("1");
        inp.setGroupBy("brand");
        inp.setMisType("1");
        inp.setMisDate("2018-02-1");
        inp.setOtherCondition( " 1=1 ");
        inp.setResult(new ArrayList<MisPrcInputResult>());
        RestResult<List<MisPrcInputResult>> result =new RestResult();
        result.setResult(1);
        misRptMapper.getMisRpt( inp);
        result.setMsg("获取成功");
        result.setData(inp.getResult());
        return  result;

    }

接口跟Service层就不贴代码了。。

最终运行结果
在这里插入图片描述

发布了5 篇原创文章 · 获赞 9 · 访问量 2782

猜你喜欢

转载自blog.csdn.net/richyliu44/article/details/104351255