全注解MyBatis调用DB2存储过程返回两个不同类型结果集如何实现
MyBatis全注解调用存储过程返回多结果集解决方案
错误原因说明
- 分开调用两次Mapper方法:每次调用存储过程都会重新执行,多结果集只能在同一次调用中按顺序读取,第二次调用依然只会返回第一个结果集,所以第二个结果集全为null。
- 泛型通配符写法:MyBatis需要明确每个结果集的映射规则,无明确映射规则的泛型写法无法完成属性映射,因此抛出
UnsupportedOperationException。
正确实现步骤
1. 定义全局ResultMap映射规则
先给两个结果集分别定义带唯一ID的@Results,注册到MyBatis上下文:
// 注册Fruit结果集映射规则 @Results(id = "fruitResultMap", value = { @Result(property = "id", column = "ID"), @Result(property = "name", column = "NAME"), @Result(property = "qty", column = "QTY") }) @Select("SELECT 1 FROM DUAL") List<Fruit> registerFruitMap(); // 该方法无需调用,仅用于注册ResultMap // 注册Animal结果集映射规则 @Results(id = "animalResultMap", value = { @Result(property = "type", column = "TYPE"), @Result(property = "num", column = "NUM"), @Result(property = "loc", column = "LOC") }) @Select("SELECT 1 FROM DUAL") List<Animal> registerAnimalMap(); // 该方法无需调用,仅用于注册ResultMap
2. 定义调用存储过程的Mapper方法
使用resultSets指定结果集顺序,@ResultMap绑定对应映射规则,返回值用List<Object>接收:
@Select( value = "{call 你的存储过程名(参数占位符)}", resultSets = {"fruitResult", "animalResult"} // 顺序必须和存储过程返回结果集的顺序一致 ) @Options(statementType = StatementType.CALLABLE) @ResultMap({"fruitResultMap", "animalResultMap"}) // 顺序和resultSets一一对应 List<Object> callProcWithTwoResultSets(Map<String, String> params);
3. 调用方法获取结果
返回的List<Object>中,第0个元素是Fruit结果集,第1个元素是Animal结果集,直接强转即可:
List<Object> result = myMapper.callProcWithTwoResultSets(params); List<Fruit> fruitList = (List<Fruit>) result.get(0); List<Animal> animalList = (List<Animal>) result.get(1);
注意事项
resultSets的顺序必须和存储过程返回结果集的顺序完全一致,否则会出现映射错乱。- 如果使用的MyBatis版本高于3.5.0,也可以省略注册ResultMap的dummy方法,直接在实体类上使用
@Alias注解配合自动映射,但显式指定ResultMap兼容性和稳定性更高。
内容的提问来源于stack exchange,提问作者Cleo
相关产品推荐
相关产品推荐

