mybatis调用oracal存储过程最佳实践

110 阅读2分钟

一、oracal存储过程

以 pkg_oms_web_maintain_iteminfo.web_pr_query_item 为例

//包名
pkg_oms_web_maintain_iteminfo

//存储过程名 packge bodies中有其具体的实现
web_pr_query_ite

参数类型

参数类型描述数据类型是否必需说明
IN输入参数,传递给存储过程的值支持所有 Oracle 数据类型参数值在过程中不可被修改。
OUT输出参数,存储过程返回的结果支持所有 Oracle 数据类型需要在过程中赋值,否则会引发异常。
IN OUT双向参数,接收输入值并返回输出值。支持所有 Oracle 数据类型。可以在存储过程中读取和修改,调用时也可以传入初始值。

二、通过mybatis调用

以查询商品信息web_pr_query_ite为例

procedure web_pr_query_item(
                                  ls_branchno in char,
                                  ls_item_no in varchar2,  
                                  ls_viptype in varchar2,
                                  iteminfo_cur out kmcur,                  
                                  itemstockprices_cur out kmcur3,   
                                  itemextinsurances out kmcur4,
                                  ls_resultcode out char,
                                  ls_resultmsg out varchar2); 

map传参

只有in参数或者out参数为String这种类型的时候使用map带参方便

mapper层定义

注意:

1.参数的传值通过map的key-value,key名称最好和存储过程的名称一致,或基于xml的映射规则,

如ls_branchno->对应lsBranchno

2.唤起存储过程是返回void,查询的结果通过游标写入传入的参数rs中,如果已有key,会覆盖,没有新建。

3.out参数的course类型只能用resultMap来接,可以不写具体映射,指定type就行

@Select("{CALL pkg_oms_web_maintain_iteminfo.web_pr_query_item("
        + "#{branchNo, mode=IN, jdbcType=CHAR}, "
        + "#{itemNo, mode=IN, jdbcType=VARCHAR}, "
        + "#{vipType, mode=IN, jdbcType=VARCHAR}, "
        + "#{iteminfoCur, mode=OUT, jdbcType=CURSOR, javaType=java.sql.ResultSet,resultMap=iteminfoCur}, "
        + "#{itemstockpricesCur, mode=OUT, jdbcType=CURSOR, javaType=java.sql.ResultSet,resultMap=itemstockpricesCur}, "
        + "#{itemextinsurances, mode=OUT, jdbcType=CURSOR, javaType=java.sql.ResultSet,resultMap=itemextinsurances}, "
        + "#{ls_resultcode, mode=OUT, jdbcType=CHAR}, "
        + "#{ls_resultmsg, mode=OUT, jdbcType=VARCHAR})"
        + "}")
@Options(statementType = StatementType.CALLABLE)
void webPrQueryItem(ItemInfoResp itemInfoResp);

xml:

<resultMap id="itemstockpricesCur" type="com.sundan.pos.modules.goods.model.vo.iteminfo.ItemStockPrice">

</resultMap>
<resultMap id="iteminfoCur" type="com.sundan.pos.modules.goods.model.vo.iteminfo.ItemInfo">

</resultMap>

<resultMap id="itemextinsurances" type="com.sundan.pos.modules.goods.model.vo.iteminfo.ItemExtInsurance">

</resultMap>

service:

public String getItemInfo(String branchNo, String itemNo, String vipType,
                          String jdeServiceUrl, String imgServiceUrl, String sheetType) {

    ArrayList<ItemInfo> itemInfos = new ArrayList<>();
    ArrayList<ItemStockPrice>  itemStockPrices= new ArrayList<>();
    ArrayList<ItemExtInsurance>  itemExtInsurances = new ArrayList<>();
    Map<String, Object> rs= new HashMap<>();
    rs.put("ls_branchno", branchNo);
    rs.put("ls_item_no", itemNo);
    rs.put("ls_viptype", vipType);
    rs.put("iteminfoCur", itemInfos);
    rs.put("itemstockpricesCur", itemStockPrices);
    rs.put("itemextinsurances", itemExtInsurances);
    rs.put("ls_resultcode", null);
    rs.put("ls_resultmsg", null);
    this.baseMapper.webPrQueryItem(rs);
    return JSON.toJSONString(rs);
}

对象传参

直接使用对象作为resVO和respVO

public class ItemInfoResp {
    private String branchNo;
    private String itemNo;
    private String vipType;
    private List<ItemInfo> iteminfoCur;
    private List<ItemStockPrice> itemstockpricesCur;
    private List<ItemExtInsuranceVO> itemextinsurances;
    private String ls_resultcode;
    private String ls_resultmsg;
}

service:

mapper和xml与之前一致,只需要保持实体按mybatis默认的映射规则能映射到存储过程的参数就行

public ItemInfoResp getItemInfo(String branchNo, String itemNo, String vipType,
                                String jdeServiceUrl, String imgServiceUrl, String sheetType) {

    ItemInfoResp resp = new ItemInfoResp();
    resp.setBranchNo(branchNo);
    resp.setItemNo(itemNo);
    resp.setVipType(vipType);
    this.baseMapper.webPrQueryItem(resp);
    return resp;
}

三、调试存储过程

选中对应存储过程,右键测试

输入变量值调试结果,通过断点查看堆栈情况