分析了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的作用已经大致分析完毕了.
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号