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及自定义扩展的更多相关文章

  1. SpringBoot(十一):springboot2.0.2下配置mybatis generator环境,并自定义字段/getter/settetr注释

    Mybatis Generator是供开发者在mybatis开发时,快速构建mapper xml,mapper类,model类的一个插件工具.它相对来说对开发者是有很大的帮助的,但是它也有不足之处,比 ...

  2. SharePoint 2013 自定义扩展菜单

    在对SharePoint进行开发或者功能扩展的时候,经常需要对一些默认的菜单进行扩展,以使我们开发的东西更适合SharePoint本身的样式.SharePoint的各种功能菜单,像网站设置.Ribbo ...

  3. SharePoint 2013 自定义扩展菜单(二)

    接博文<SharePoint 2013 自定义扩展菜单>,多加了几个例子,方便大家理解. 例七 列表设置菜单扩展(listedit.aspx) 扩展效果 XML描述 <CustomA ...

  4. WCF自定义扩展,以实现aop!

    引用地址:https://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx  使用自定义行为扩展 WCF Aaron Skonnard 代码下载位置: S ...

  5. Jquery自定义扩展方法(二)--HTML日历控件

    一.概述 研究了上节的Jquery自定义扩展方法,自己一直想做用jquery写一个小的插件,工作中也用到了用JQuery的日历插件,自己琢磨着去造个轮子--HTML5手机网页日历控件,废话不多说,先看 ...

  6. Silverlight实例教程 - 自定义扩展Validation类,验证框架的总结和建议(转载)

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  7. jQuery 自定义扩展,与$冲突处理

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件

    需求   SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件   扩展   class SparkContext(pyspark.SparkContext): def ...

  9. 基于 HtmlHelper 的自定义扩展Container

    基于 HtmlHelper 的自定义扩展Container Intro 基于 asp.net mvc 的权限控制系统的一部分,适用于对UI层数据呈现的控制,基于 HtmlHelper 的扩展组件 Co ...

随机推荐

  1. 一次 Young GC 的优化实践(FinalReference 相关)

    本文转载自公众号:涤生的博客,阅读时间大约需要11分钟.涤生的文章看起来跟破案一样,很精彩,很有启发. 前言 博客已经好久没有更新了,主要原因是 18 年下半年工作比较忙,另外也没有比较有意思的题材, ...

  2. VS2015配置Qt5

    目录 需要准备的东西 VS2015 Qt5 VS2015 Qt插件 rc.exe无法启动 基于CMake的Qt工程 reference 需要准备的东西 Visual Studio 2015 Qt5 V ...

  3. js刷新页面得重新加载和页面的刷新

    1.reload 方法,该方法强迫浏览器刷新当前页面. 语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当 ...

  4. 如何让自己的Dev C++用上C++11标准

    首先确保Dev C++版本是最新的5.11版 其实用C++11标准的语法去运行还是会出现结果的,最多warning一下 但完美主义者是不允许这样的 我们可以点击菜单栏的“工具”->“编译选项”进 ...

  5. JavaFX 井字棋游戏

    利用JavaFX设计一个井字棋游戏,其中包括了能够与玩家对战的AI.AI的实现相比五子棋来说要简单得多,可以保证AI在后手情况下绝对不会输,具体实现如下: /* * To change this li ...

  6. 201671030111 李蓉 实验十四 团队项目评审&课程学习总结

    项目 内容 这个作业属于哪个课程 软件工程 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 掌握软件项目评审会流程,反思总结课程学习内容. 任务一:结合本学期课程学习 ...

  7. 17、Python面向对象高级

    一.isinstance和issubclass type():不会认为子类实例是一种父类类型: isinstance():认为子类实例是一种父类类型. issubclass():判断是否为其子类. c ...

  8. 教你如何解决WIN 10系统睡眠无法唤醒

    1.右击“开始菜单”,选择“电源选项”.   2.选择“更改计算机睡眠时间”. 3.选择“更改高级电源设置”.   4.选择“还原计划默认值”.   5.在弹出的对话框中选择“是 ”.   6.最后选 ...

  9. 在Maven项目中,jsp不解析el表达式

    我的这个项目是用Maven-archetype-webapp项目创建的,如下图所示: 有这种方式创建有一个坑,就是它使用的servlet版本是2.3,而servlet2.4以下的版本是不会自动解析el ...

  10. vue基于iview树状表格,封装完善

    先安装iview后在使用 完善按钮不显示问题 ,当children过多时,点击不动问题等 封装 <template> <div :style="{width:tableWi ...