mybatis ResultHandler vs ResultSetHandler及自定义扩展
ResultSetHandler是mybatis的关键类之一,用于对jdbc返回的ResultSet进行映射处理,其中包括列前缀处理,逻辑分页,鉴别器(Discriminator,基于值实现动态映射列)处理等等。
ResultSetHandler在StatementHandler执行过程中构建,如下:

接下去来看ResultSetHandler的定义。最主要的是handleResultSets,它负责普通查询结果的处理。
public interface ResultSetHandler {
<E> List<E> handleResultSets(Statement var1) throws SQLException;
<E> Cursor<E> handleCursorResultSets(Statement var1) throws SQLException;
void handleOutputParameters(CallableStatement var1) throws SQLException;
}
handleResultSets在StatementHandler执行完成后被调用,如下:

要对结果集自定义处理的话,可以改动此处源码。因为mybatis拦截器支持对四大对象(Executor,StatementHandler,ParameterHandler,ResultSetHandler)都支持,所以也可以通过拦截器(参见mybatis自定义插件开发详解)实现,各有利弊,LZ采用后者。
逻辑分页也是在handleResultSets中处理。逻辑分页由org.apache.ibatis.session.RowBounds实现,mybatis内置的应用层逻辑分页实现定义,但基本上很少使用,定义如下。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.apache.ibatis.session; public class RowBounds {
public static final int NO_ROW_OFFSET = 0;
public static final int NO_ROW_LIMIT = 2147483647;
public static final RowBounds DEFAULT = new RowBounds();
private final int offset;
private final int limit; public RowBounds() {
this.offset = 0;
this.limit = 2147483647;
} public RowBounds(int offset, int limit) {
this.offset = offset;
this.limit = limit;
} public int getOffset() {
return this.offset;
} public int getLimit() {
return this.limit;
}
}
默认值为不分页。在shouldProcessMoreRows中判断,如下:
private boolean shouldProcessMoreRows(ResultContext<?> context, RowBounds rowBounds) throws SQLException {
return !context.isStopped() && context.getResultCount() < rowBounds.getLimit();
}
在处理每一行记录的时候,先处理没有明确映射(无或不在ResultMap中)的属性,然后处理明确映射,如下:
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQLException {
ResultLoaderMap lazyLoader = new ResultLoaderMap();
// 创建目标类型对象,如Pojo或Map
Object rowValue = this.createResultObject(rsw, resultMap, lazyLoader, (String)null);
if (rowValue != null && !this.hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
MetaObject metaObject = this.configuration.newMetaObject(rowValue);
boolean foundValues = this.useConstructorMappings;
if (this.shouldApplyAutomaticMappings(resultMap, false)) {
// map就是在这里自动映射的
foundValues = this.applyAutomaticMappings(rsw, resultMap, metaObject, (String)null) || foundValues;
}
foundValues = this.applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, (String)null) || foundValues;
foundValues = lazyLoader.size() > 0 || foundValues;
rowValue = !foundValues && !this.configuration.isReturnInstanceForEmptyRow() ? null : rowValue;
}
return rowValue;
}
接下去再来看ResultHandler,它用来对每行记录映射或处理,典型的比如二次过滤或脱敏处理,都可以在这里处理,当然也可以通过插件,只不过在这里处理从性能上看最佳。其定义比较简单:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package org.apache.ibatis.session; public interface ResultHandler<T> {
void handleResult(ResultContext<? extends T> var1);
}

相对来说,ResultHandler的实现很简单,这里就不详解了,真的想了解的可以参考https://www.cnblogs.com/51life/p/9633002.html。
mybatis ResultHandler vs ResultSetHandler及自定义扩展的更多相关文章
- SpringBoot(十一):springboot2.0.2下配置mybatis generator环境,并自定义字段/getter/settetr注释
Mybatis Generator是供开发者在mybatis开发时,快速构建mapper xml,mapper类,model类的一个插件工具.它相对来说对开发者是有很大的帮助的,但是它也有不足之处,比 ...
- SharePoint 2013 自定义扩展菜单
在对SharePoint进行开发或者功能扩展的时候,经常需要对一些默认的菜单进行扩展,以使我们开发的东西更适合SharePoint本身的样式.SharePoint的各种功能菜单,像网站设置.Ribbo ...
- SharePoint 2013 自定义扩展菜单(二)
接博文<SharePoint 2013 自定义扩展菜单>,多加了几个例子,方便大家理解. 例七 列表设置菜单扩展(listedit.aspx) 扩展效果 XML描述 <CustomA ...
- WCF自定义扩展,以实现aop!
引用地址:https://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx 使用自定义行为扩展 WCF Aaron Skonnard 代码下载位置: S ...
- Jquery自定义扩展方法(二)--HTML日历控件
一.概述 研究了上节的Jquery自定义扩展方法,自己一直想做用jquery写一个小的插件,工作中也用到了用JQuery的日历插件,自己琢磨着去造个轮子--HTML5手机网页日历控件,废话不多说,先看 ...
- Silverlight实例教程 - 自定义扩展Validation类,验证框架的总结和建议(转载)
Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...
- jQuery 自定义扩展,与$冲突处理
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件
需求 SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件 扩展 class SparkContext(pyspark.SparkContext): def ...
- 基于 HtmlHelper 的自定义扩展Container
基于 HtmlHelper 的自定义扩展Container Intro 基于 asp.net mvc 的权限控制系统的一部分,适用于对UI层数据呈现的控制,基于 HtmlHelper 的扩展组件 Co ...
随机推荐
- 一次 Young GC 的优化实践(FinalReference 相关)
本文转载自公众号:涤生的博客,阅读时间大约需要11分钟.涤生的文章看起来跟破案一样,很精彩,很有启发. 前言 博客已经好久没有更新了,主要原因是 18 年下半年工作比较忙,另外也没有比较有意思的题材, ...
- VS2015配置Qt5
目录 需要准备的东西 VS2015 Qt5 VS2015 Qt插件 rc.exe无法启动 基于CMake的Qt工程 reference 需要准备的东西 Visual Studio 2015 Qt5 V ...
- js刷新页面得重新加载和页面的刷新
1.reload 方法,该方法强迫浏览器刷新当前页面. 语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当 ...
- 如何让自己的Dev C++用上C++11标准
首先确保Dev C++版本是最新的5.11版 其实用C++11标准的语法去运行还是会出现结果的,最多warning一下 但完美主义者是不允许这样的 我们可以点击菜单栏的“工具”->“编译选项”进 ...
- JavaFX 井字棋游戏
利用JavaFX设计一个井字棋游戏,其中包括了能够与玩家对战的AI.AI的实现相比五子棋来说要简单得多,可以保证AI在后手情况下绝对不会输,具体实现如下: /* * To change this li ...
- 201671030111 李蓉 实验十四 团队项目评审&课程学习总结
项目 内容 这个作业属于哪个课程 软件工程 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 掌握软件项目评审会流程,反思总结课程学习内容. 任务一:结合本学期课程学习 ...
- 17、Python面向对象高级
一.isinstance和issubclass type():不会认为子类实例是一种父类类型: isinstance():认为子类实例是一种父类类型. issubclass():判断是否为其子类. c ...
- 教你如何解决WIN 10系统睡眠无法唤醒
1.右击“开始菜单”,选择“电源选项”. 2.选择“更改计算机睡眠时间”. 3.选择“更改高级电源设置”. 4.选择“还原计划默认值”. 5.在弹出的对话框中选择“是 ”. 6.最后选 ...
- 在Maven项目中,jsp不解析el表达式
我的这个项目是用Maven-archetype-webapp项目创建的,如下图所示: 有这种方式创建有一个坑,就是它使用的servlet版本是2.3,而servlet2.4以下的版本是不会自动解析el ...
- vue基于iview树状表格,封装完善
先安装iview后在使用 完善按钮不显示问题 ,当children过多时,点击不动问题等 封装 <template> <div :style="{width:tableWi ...