如何通过MyBatis注解调用存储过程获取游标返回的List数据?
MyBatis调用带游标输出的存储过程实现方案
1. 定义结果封装DTO
因为存储过程同时返回return_code、return_msg和游标数据,建议创建一个DTO类统一接收所有输出:
public class SampleProcResult { private String returnCode; private String returnMsg; private List<Sample> sampleList; // 生成对应的getter、setter方法 }
2. 修正Mapper接口方法
原方法直接返回List<Sample>无法接收额外的字符串输出参数,需要调整方法结构,并指定存储过程调用类型:
@Select("{ call SAMPLES.INSERT_T_SAMPLE ( " + "#{sampleId,jdbcType=INTEGER, mode=IN}," + "#{result.sampleList,jdbcType=SYS_REFCURSOR, mode=OUT, resultMap=SampleResultMap}, " + "#{result.returnCode,jdbcType=VARCHAR, mode=OUT}, " + "#{result.returnMsg,jdbcType=VARCHAR, mode=OUT} )}") @Options(statementType = StatementType.CALLABLE) public void getSamplesById(@Param("sampleId") Integer sampleId, @Param("result") SampleProcResult result);
注意点:
- 统一参数名:原方法的
Id和SQL里的sampleId不匹配,这里改为一致的sampleId,且类型要和存储过程定义的INTEGER对应(原String类型需转成Integer) - 通过
@Param("result")传入DTO对象,SQL里用#{result.xxx}绑定输出参数 - 游标参数需指定
resultMap,用来映射游标返回的记录到Sample对象
3. 配置ResultMap映射游标数据
如果用XML配置:
<resultMap id="SampleResultMap" type="com.yourpackage.Sample"> <id column="sample_id" property="sampleId"/> <result column="sample_name" property="sampleName"/> <!-- 根据实际表结构补充其他字段映射 --> </resultMap>
如果用注解式配置,直接在Sample类上定义:
@Results(id = "SampleResultMap", value = { @Result(column = "sample_id", property = "sampleId", id = true), @Result(column = "sample_name", property = "sampleName") // 补充其他字段映射 }) public class Sample { // 类字段定义 }
4. 业务代码调用获取结果
// 创建结果接收对象 SampleProcResult result = new SampleProcResult(); // 调用存储过程 sampleMapper.getSamplesById(Integer.parseInt(id), result); // 从DTO中取出数据 List<Sample> sampleList = result.getSampleList(); String returnCode = result.getReturnCode(); String returnMsg = result.getReturnMsg();
关键细节
- 存储过程SQL末尾不要加多余逗号,原代码最后有个无效逗号会导致语法错误
- 游标类型
SYS_REFCURSOR是Oracle数据库的标准类型,若使用其他数据库(如MySQL),需替换为对应数据库的游标类型 - 确保输入参数的类型、jdbcType与存储过程定义完全匹配
内容的提问来源于stack exchange,提问作者Amigma
相关产品推荐
相关产品推荐

