文档章节

mybatis源码分析之TypeHandler

u
 udbwcso
发布于 2016/11/18 16:47
字数 566
阅读 601
收藏 15

上一篇:

mybatis源码分析之MapperMethod

https://my.oschina.net/u/657390/blog/755787

分析了MapperMethod从创建到执行的过程,MapperMethod的执行包括执行sql返回结果.

在执行sql和返回结果的过程中就会涉及到参数类型的转换,这个过程是通过TypeHandler来处理的.关于TypeHandler官网有比较详细的文档http://www.mybatis.org/mybatis-3/zh/configuration.html#typeHandlers,文档主要说明了如何使用TypeHandler,在下面的分析中将重点分析与TypeHandler有关的源码.

1.配置

MyBatis有默认的类型处理器,如果需要自定义配置也相当简单,在mybatis-config.xml里添加如下配置:

<typeHandlers>
  <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/>
</typeHandlers>

下面分析配置读取设置的过程,在XMLConfigBuilder中

    /**
     * 读取配置文件组装configuration
     * @param root 配置文件的configuration节点
     */
  private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      loadCustomVfs(settings);
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      settingsElement(settings);
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

在以上源码中有一行

typeHandlerElement(root.evalNode("typeHandlers"));

再来看typeHandlerElement这个方法

/**
   * 读取typeHandlers配置并注册
   * @param parent 配置文件typeHandlers节点
   * @throws Exception
   */
  private void typeHandlerElement(XNode parent) throws Exception {
    if (parent != null) {
      for (XNode child : parent.getChildren()) {
        if ("package".equals(child.getName())) {
          String typeHandlerPackage = child.getStringAttribute("name");
          typeHandlerRegistry.register(typeHandlerPackage);
        } else {
          String javaTypeName = child.getStringAttribute("javaType");
          String jdbcTypeName = child.getStringAttribute("jdbcType");
          String handlerTypeName = child.getStringAttribute("handler");
          Class<?> javaTypeClass = resolveClass(javaTypeName);
          JdbcType jdbcType = resolveJdbcType(jdbcTypeName);
          Class<?> typeHandlerClass = resolveClass(handlerTypeName);
          if (javaTypeClass != null) {
            if (jdbcType == null) {
              typeHandlerRegistry.register(javaTypeClass, typeHandlerClass);
            } else {
              typeHandlerRegistry.register(javaTypeClass, jdbcType, typeHandlerClass);
            }
          } else {
            typeHandlerRegistry.register(typeHandlerClass);
          }
        }
      }
    }
  }

if和else中的代码逻辑对应了typeHandler的两种配置方式.最后都会调用 

typeHandlerRegistry.register()

以上是TypeHandler与TypeHandlerRegistry,Configuration,BaseTypeHandler之间的关系.

2.设置参数

设置参数时先调用ParameterHandler.setParameters(),然后在setParameters()里获取相应的typeHandler,最后调用typeHandler.setParameter()

再来看看BaseTypeHandler的setParameter方法

当parameter不为null时调用的是setNonNullParameter,也就是说子类需要实现setNonNullParameter

BigIntegerTypeHandler的源码:

  public void setNonNullParameter(PreparedStatement ps, int i, BigInteger parameter, JdbcType jdbcType) throws SQLException {
    ps.setBigDecimal(i, new BigDecimal(parameter));
  }

至此,TypeHandler的作用已经大致分析完毕了.

© 著作权归作者所有

u
粉丝 86
博文 66
码字总数 15709
作品 0
武汉
私信 提问
mybatis(五)TypeHandler简介及配置(mybatis源码篇)

上篇文章为大家介绍了mybatis中别名的使用,以及其源码。本篇将为大家介绍TypeHandler, 并简单分析其源码。 Mybatis中的TypeHandler是什么?   无论是 MyBatis 在预处理语句(PreparedSta...

LCZ777
2014/12/19
90
0
Mybatis 类型转换源码分析

本文将从以下几个方面进行介绍 相关文章 前言 类型处理器 类型注册器 别名注册器 相关文章 Mybatis 解析配置文件的源码解析 前言 JDBC 提供的数据类型和Java的数据类型并不是完全对应的,当 ...

tsmyk0715
2018/11/04
364
0
Mybatis3.3.x技术内幕(十二):Mybatis之TypeHandler

Mybatis中的TypeHandler有两个功能,一个是完成javaType至jdbcType的转换,另外一个是完成jdbcType至javaType的转换。 public interface TypeHandler<T> { void setParameter(PreparedStatem......

祖大俊
2016/05/06
1K
0
【深入浅出MyBatis系列二】配置简介(MyBatis源码篇)

深入浅出MyBatis系列 【深入浅出MyBatis系列一】MyBatis入门 【深入浅出MyBatis系列二】配置简介(MyBatis源码篇) 【深入浅出MyBatis系列三】Mapper映射文件配置 【深入浅出MyBatis系列四】...

陶邦仁
2015/12/22
3.3K
4
Mybatis3.3.x技术内幕(十):Mybatis初始化流程(下)

Mybatis初始化过程中,解析parameterMap、resultMap、"select|insert|update|delete"元素,无疑是重头戏。本节将详细分析解析过程。 元素parameterMap将会解析为ParameterMap对象,该对象包含...

祖大俊
2016/05/04
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

高级技术题整理

1. 为什么等待和通知是在 Object 类而不是 Thread 中声明的? 一个棘手的 Java 问题,如果 Java编程语言不是你设计的,你怎么能回答这个问题呢。Java编程的常识和深入了解有助于回答这种棘手...

泉天下
20分钟前
2
0
Elasticsearch

1 、下载 下载地址:https://www.elastic.co/downloads/past-releases 2 、安装 elasticsearch无需安装,解压即用。 3.运行 进入elasticsearch/bin目录,可以看到下面的执行文件: 双击运行 ...

少年已不再年少
20分钟前
5
0
Spring Boot 2.X(七):Spring Cache 使用

Spring Cache 简介 在 Spring 3.1 中引入了多 Cache 的支持,在 spring-context 包中定义了org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 两个接口来统一不同......

朝雾轻寒
22分钟前
3
0
java路径问题

在Java中有几种常见获取文件路径的方法,此处演示下用法和效果。 测试项目目录结构如右图: 1、使用File类 File file = new File("");// Java项目中-->D:\WorkSoftware\Workspace\EclipseP...

随心の随缘
25分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部