博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mybatis源码分析之TypeHandler
阅读量:6551 次
发布时间:2019-06-24

本文共 3395 字,大约阅读时间需要 11 分钟。

hot3.png

上一篇:

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

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

1.配置

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

下面分析配置读取设置的过程,在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的作用已经大致分析完毕了.

转载于:https://my.oschina.net/u/657390/blog/790456

你可能感兴趣的文章
我的友情链接
查看>>
负载均衡集群解决方案 (一)LVS-DR
查看>>
前端之Bootstrap框架
查看>>
apache 配置https 支持ssl
查看>>
优化网站波动原因分析及解决措施分享篇
查看>>
freemarker.core.InvalidReferenceException: Expression persons is undefined
查看>>
怎么操作linux用户和组
查看>>
nginx安全优化之隐藏版本
查看>>
高并发高流量网站架构详解
查看>>
网游服务器搭建方案图解(以魔兽世界为例)
查看>>
redis配置文件详解
查看>>
mysql全局变量和局部变量
查看>>
WEB服务之httpd2.2与2.4
查看>>
阅读笔记之<c++对象模型>
查看>>
关于java中字符串截取
查看>>
多个eclipse插件导出同名且版本不同的包带来的问题之分析过程
查看>>
我的友情链接
查看>>
CSS禁止文字选中
查看>>
计算机应用一级B考试专题整理三
查看>>
Python-7 多继承函数调用注意点
查看>>