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
相关产品推荐
相关产品推荐

