You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MyBatis 3调用返回双结果集存储过程遇问题求助

处理MyBatis 3中调用返回多结果集的存储过程

我来帮你搞定这个问题!在MyBatis 3里调用返回两个结果集的存储过程,其实只要正确配置Mapper XML和对应的接口方法就能轻松解决,下面一步步给你讲清楚:

1. 配置Mapper XML中的存储过程调用

首先,你需要在Mapper XML里定义调用存储过程的<select>标签,注意要设置statementType="CALLABLE"来标识这是调用存储过程。这里有两种常用的配置方式:

方式一:直接指定多个ResultMap

如果不需要给结果集命名,直接用逗号分隔多个ResultMap的ID即可:

<select id="invokeDualResultProcedure" statementType="CALLABLE" resultMap="object1,object2">
    <!-- 替换成你的存储过程调用语句,参数根据实际情况配置IN/OUT模式 -->
    {call your_stored_procedure(#{inputParam, mode=IN, jdbcType=VARCHAR})}
</select>

方式二:给结果集命名(更清晰)

如果想给每个结果集指定明确的名称,方便后续获取,可以用<resultSet>标签:

<select id="invokeDualResultProcedure" statementType="CALLABLE">
    {call your_stored_procedure(#{inputParam, mode=IN, jdbcType=VARCHAR})}
    <!-- 第一个结果集对应object1的ResultMap -->
    <resultSet id="object1Results" resultMap="object1"/>
    <!-- 第二个结果集对应object2的ResultMap -->
    <resultSet id="object2Results" resultMap="object2"/>
</select>

2. 定义Mapper接口方法

根据上面的配置,你可以选择不同的返回类型,推荐两种类型安全的方式:

选项A:返回Map(灵活但需要强转)

如果用方式二的命名结果集,Map的键就是你在<resultSet>里定义的ID,值是对应POJO的列表:

import java.util.List;
import java.util.Map;

public interface YourMapper {
    Map<String, List<?>> invokeDualResultProcedure(String inputParam);
}

调用的时候直接获取即可:

// 在Service层调用
Map<String, List<?>> resultMap = yourMapper.invokeDualResultProcedure("testParam");
List<Object1> object1List = (List<Object1>) resultMap.get("object1Results");
List<Object2> object2List = (List<Object2>) resultMap.get("object2Results");

选项B:返回自定义包装类(类型安全)

如果你不想做类型强转,可以定义一个包装类来封装两个结果集:

import java.util.List;

public class ProcedureResult {
    private List<Object1> object1List;
    private List<Object2> object2List;

    // 生成getter和setter方法
    public List<Object1> getObject1List() {
        return object1List;
    }

    public void setObject1List(List<Object1> object1List) {
        this.object1List = object1List;
    }

    public List<Object2> getObject2List() {
        return object2List;
    }

    public void setObject2List(List<Object2> object2List) {
        this.object2List = object2List;
    }
}

然后在Mapper XML里新增一个对应这个包装类的ResultMap:

<resultMap id="procedureResultMap" type="com.yourpackage.ProcedureResult">
    <!-- 关联第一个结果集到object1List属性 -->
    <collection property="object1List" resultMap="object1"/>
    <!-- 关联第二个结果集到object2List属性 -->
    <collection property="object2List" resultMap="object2"/>
</resultMap>

修改<select>标签的resultMap属性为这个新的ResultMap:

<select id="invokeDualResultProcedure" statementType="CALLABLE" resultMap="procedureResultMap">
    {call your_stored_procedure(#{inputParam, mode=IN, jdbcType=VARCHAR})}
</select>

最后Mapper接口方法返回这个包装类:

public interface YourMapper {
    ProcedureResult invokeDualResultProcedure(String inputParam);
}

调用的时候就非常直观了:

ProcedureResult result = yourMapper.invokeDualResultProcedure("testParam");
List<Object1> object1List = result.getObject1List();
List<Object2> object2List = result.getObject2List();

3. 注意事项

  • 确保你的存储过程确实返回了两个结果集,没有遗漏或者顺序错误(MyBatis会按结果集返回的顺序映射到对应的ResultMap)。
  • 如果是MySQL数据库,需要确保JDBC URL中添加了allowMultiQueries=true参数,否则驱动可能无法正确处理多结果集。
  • 存储过程的参数配置要正确,IN/OUT/INOUT模式要和存储过程定义一致,jdbcType也要匹配。

内容的提问来源于stack exchange,提问作者Ali CHAHIB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:14:53