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. Android 8.0编译过程

    Android编译系统中的Android.bp.Blueprint与Soonghttp://note.qidong.name/2017/08/android-blueprint/ 工具链关系 Andr ...

  2. windows ssh远程登录阿里云遇到permissions are too open的错误

    我试图用ssh -i 命令远程登录阿里云时,遇到如下错误: Permissions for 'private-key.ppk' are too open. It is required that yo ...

  3. 从CMS到G1:LinkedIn个人主页调优实战

    本文转载自公众号:阿飞的博客,阅读大约需要13分钟.阿飞是我认识几年的好友,对技术有很强的专研精神,跟他讨论GC问题的时候一些观点都很深刻. LinkedIn中的个人主页是访问量最多的页面之一,它允许 ...

  4. Executor的线程代码

    package com.open1111; import java.util.concurrent.ExecutorService;import java.util.concurrent.Execut ...

  5. set_lb

    修改lb权重,通知钉钉 前提需要安装阿里的核心库 #!/usr/local/python-3.6.4/bin/python3 #coding=utf-8 from aliyunsdkcore.clie ...

  6. 将浏览器地址栏中的 Request 参数显示成中文

    希望实现:在当 JSP 页面发起请求,或者 Servlet 跳转时,地址栏中的参数可以显示成中文. 在通常情况下,浏览器地址栏中的URL地址为了适配不同的浏览器,会将URL地址信息转码为"I ...

  7. Linux运维技术之详解任务计划(crontab命令)

    crontab命令 按照预先设置的时间周期(分钟.小时.天……)重复执行用户指定的命令操作,属于周期性计划任务 (1).先来看一下/etc/crontab文件的内容: [root@localhost ...

  8. linux下activemq安装与配置activemq-5.15.2

    linux下activemq安装与配置 前提 配置好jdk环境   一.下载:apache-activemq-5.15.2-bin.tar.gz https://archive.apache.org/ ...

  9. 直接将字典转为DataFrame格式时,会出现:ValueError: If using all scalar values, you must pass an index(四种解决方案)

    问题:想要将字典直接转为DataFrame格式时,除了字典外没有传入其他参数时,会报错 ValueError: If using all scalar values, you must pass an ...

  10. Linux四剑客之awk命令

    AWK详解   awk简介 awk其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的首个字母.实际上 AWK 的确拥有自己的语 ...