阅读指引
- 一、使用场景
- 二、前提条件
- 三、源码对照
- 四、使用示例
- 目标
- 实现方式
一、使用场景
对Mybatis查询的结果集进行统一批量处理,如进行类型转换、数据变更等等。
二、前提条件
- 必须是查询语句。
- mapper方法的返回值必须是void,这也就是不能直接从这个方法获取到查询结果集,需要在ResultHandler里面自己存放查询结果。
- mapper方法必须传入自定义的结果处理器。
三、源码对照
- 方法执行入口,org.apache.ibatis.binding.MapperMethod#execute:
- 根据获取方法参数中ResultHandler.class类型的变量作为结果处理器:
- org.apache.ibatis.binding.MapperMethod#executeWithResultHandler,可以看到executeWithResultHandler方法无返回值。
四、使用示例
目标
将原查询结果的Map转为Record,Record可以理解为将Map进行包装了一次的实体类,代码结构如下:
public class Record implements Serializable {
private static final long serialVersionUID = 905784513600884082L;
private Map<String, Object> columns;
void setColumnsMap(Map<String, Object> columns) {
this.columns = columns;
}
......
}
这种如果直接使用mybatis进行构造返回结果是比较麻烦,特别是使用的地方比较多,会有很多冗余代码。
实现方式
- 自定义ResultHandler代码
public class RecordResultHandler implements ResultHandler<Record> {
private final List<Record> list = new ArrayList<>();
@Override
public void handleResult(ResultContext context) {
Record record = new Record();
record.setColumns((Map<String, Object>) context.getResultObject());
list.add(record);
}
public List<Record> getResults(){
return list;
}
}
- xml代码
<select id="test" resultType="map">
select * from user_test
</select>
- Mapper层代码
//必须返回void且传入ResultHandler
void test(ResultHandler recordResultHandler);
- 调用层代码
RecordResultHandler recordResultHandler = new RecordResultHandler();
//integDataMapper正常注入即可
integDataMapper.test(recordResultHandler);
List<Record> results = recordResultHandler.getResults();
- 执行结果
可以看到已经返回了Record类型的数据