[Mybatis]-[基础支持层]-类型转换处理-typeHandler

it2023-02-06  53

该系列文章针对 Mybatis 3.5.1 版本

一、TypeHandler 类型处理器介绍

MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用typeHandler类型处理器将获取到的值以合适的方式转换成 Java 类型,或者将 Java 类型映射成数据库支持的类型。

在 Mybatis 中内置了很多的 TypeHandler ,这些内置的 TypeHandler 存储在了 TypeHandlerRegistry 容器中。

如下图,在 TypeHandlerRegistry 构造函数中,初始化了几乎所有使用类型的TypeHandler

在 Mybatis 中除了内置的 TypeHandler ,Mybaits 允许自定义 TypeHandler 并将其注册到 TypeHandlerRegistry 容器中。

TypeHandlerRegistry 容器会以属性值的方式,存在于 Configuration 对象中。

二、配置加载外部 typeHandler

2.1、配置方式

自定义 TypeHandler 相关配置信息配置在 mybatis-config.xml 中的 <typeHandlers>标签下,配置的方式有两种

1、通过 <package> 配置 多个 typeHandler所在的包路径,通过扫包的方式批量设置

2、通过 <typeHandler> 标签,一个一个进行 typeHandler 配置

typeHandler 在 mybaits-config.xml 配置案例如下:

2.1、配置加载解析

回顾下XMLConfigBuilder 解析时序图

如图,<typeHandler> 标签的解析代码在 XMLConfigBuilder#typeHandlerElement 中,具体解析代码如下:

在上述代码中主要分别对两种 typeHandler 配置方式进行解析。

XMLConfigBuilder 借助 XPathParser 进行标签数据解析,根据获取到的解析内容调用 TypeHandlerRegistry 的注册方法,进行 TypeHandler 的注册操作。

所以 XMLConfigBuilder 针对标签 <typeHandlers> 及其子标签只是进行单纯的数据组装,解析由 XPathParser 完成,存储则由 TypeHandlerRegistry 完成。

然后再把 TypeHandlerRegistry 作为属性值存储在 Configuration 对象中。 将所有的 typeHandler 信息存到了 TypeHandlerRegistry 中。

2.2、TypeHandlerRegistry

TypeHandlerRegistry 是一个容器,该容器是用来存放 Mybatis 运行期间所有的 TypeHandler 。

来看一下容器 TypeHandlerRegistry 是如何存放数据的,相关代码如下:

如上述代码,针对 TypeHandler 的存储基本上都是 key-value 的方式进行存储,使得同一个 TypeHandler 能够通过各种类型的 key 进行获取。

再来看一下,TypeHandlerRegistry 对外提供的注册方法

如图,注册的重载方法有点多,不过实现方式大同小异,这里来看一下关于包配置的注册逻辑,也就是 <typeHandlers> 下的子标签 <package> 配置的扫包注册操作。

代码如下:

上述代码进行 TypeHandler 注册主流程为:

1、根据包名获取 class 文件

2、ClassLoader 加载 class 文件,过滤出为 TypeHandler 实现类的 class 文件

3、对 class 在进行一次过滤,去除内部类、接口类、package-info.java 类

4、将过滤完后的类存储到 TypeHandlerRegistry 的容器中

上述代码还没有进行真正的注册操作,只是进行 TypeHandler 查找和过滤,具体具体流程可以自行查阅。

三、总结

在加入了 TypeHandler 类型处理器后,Mybatis 整体的运行框架如下:


文章实时更新关注公众号

最新回复(0)