通用源码阅读指导mybatis源码详解:type包

2021年01月01日00:20:16 娱乐 1118

type包

type包中的类有 55个之多。在遇到这种繁杂的情况时,一定要注意归类总结。

归类总结是源码阅读中非常好的办法。往往越是大量的类,越是大量的方法,越有规律进行分类。这些原本繁杂的类和方法经过分类后,可能会变得很有条理。

经过梳理后,我们把 type包内的类分为以下六组。

· 类型处理器:1个接口、1个基础实现类、1个辅助类、43个实现类。

-TypeHandler:类型处理器接口;

-BaseTypeHandler:类型处理器的基础实现;

-TypeReference:类型参考器;

-*TypeHandler:43个类型处理器。

· 类型注册表:3个。

-SimpleTypeRegistry:基本类型注册表,内部使用 Set 维护了所有 Java 基本数据类型的集合;

-TypeAliasRegistry:类型别名注册表,内部使用 HashMap维护了所有类型的别名和类型的映射关系;

-TypeHandlerRegistry:类型处理器注册表,内部维护了所有类型与对应类型处理器的映射关系。

· 注解类:3个。

-Alias:使用该注解可以给类设置别名,设置后,别名和类型的映射关系便存入TypeAliasRegistry中;

-MappedJdbcTypes:有时我们想使用自己的处理器来处理某些 JDBC 类型,只需创建 BaseTypeHandler 的子类,然后在上面加上该注解,声明它要处理的JDBC类型即可;

-MappedTypes:有时我们想使用自己的处理器来处理某些Java类型,只需创建BaseTypeHandler的子类,然后在上面加上该注解,声明它要处理的 Java类型即可。

· 异常类:1个。

-TypeException:表示与类型处理相关的异常。

· 工具类:1个。

-ByteArrayUtils:提供数组转化的工具方法。

· 枚举类:1个。

-JdbcType:在 Enum中定义了所有的 JDBC类型,类型来源于 java.sql.Types。

以上类中,注解类、异常类、工具类、枚举类都非常简单,不再单独介绍。下面将重点介绍类型处理器和类型注册表。

模板模式

说起模板大家应该都很熟悉。一般情况下,模板中规定了大体的框架,只留下一些细节供使用者来修改和完善。使用同一模板做出的不同产品都具有一致的框架。设计模式中的模板模式与上述模板的概念相同。在模板模式中,需要使用一个抽象类定义一套操作的整体步骤(即模板),而抽象类的子类则完成每个步骤的具体实现。这样,抽象类的不同子类遵循了同样的一套模板。

例如,我们定义一套打扫卫生的模板,如代码8-1 所示。它为所有的打扫卫生工作定义了四个大的步骤:准备(prepare)、实施(implement)、善后(windup)和汇报(report)。

【代码8-1】

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

这样,就可以基于该模板完成一些具体的打扫卫生工作。例如,代码8-2 和代码8-3分别给出了擦玻璃和擦黑板的实现。

【代码8-2】

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

【代码8-3】

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

可以看到,虽然具体的行为不同,但是 WipeGlass和 WipeBlackboard两者遵循的模板是一样的,都是由 Cleaning类给定的。这就是模板模式的作用,即确定了一套操作的框架,而子类只需在此框架的基础上定义具体的实现即可。

类型处理器

类型处理器的基类与实现类

作为一个 ORM框架,处理 Java对象和数据库关系之间的映射是 MyBatis工作中的重要部分。然而在 Java中存在 Integer、String、Data等各种类型的数据,在数据库中也存在varchar、longvarchar、tinyint等各种类型的数据。不同类型的字段所需的读、写方法各不相同,因此需要对不同类型的字段采取相应的处理方式。

例如,User中有如代码8-4所示的几个属性。

【代码8-4】

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

在对 User对象的属性进行读取和赋值时,需要用 Integer的相关处理方式来操作 id、sex属性,而要用 String的相关处理方式来操作name、schoolName属性。

在 type包中,将每种类型对应的处理方式封装在了对应的类型处理器 TypeHandler中。例如,IntegerTypeHandler负责完成对 Integer类型的处理。

type 包共有 43 个类型处理器,这些类型处理器的名称也均以“TypeHandler”结尾。而 TypeHandler和 BaseTypeHandler则分别是类型处理器接口和类型处理器基类。

图8-1展示了type包中类型处理器相关的类图。

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

图8-1 类型处理器类图

TypeHandler<T>是一个接口,其中定义了进行数据处理操作的几个抽象方法。而BaseTypeHandler<T>继承了 TypeHandler<T>接口,并实现了 TypeHandler<T>中的接口。

在类型处理器相关类的设计中采用了模板模式,BaseTypeHandler<T>作为所有类型处理器的基类,定义了模板的框架。而在各个具体的实现类中,则实现了具体的细节。

以代码8-5展示的 BaseTypeHandler中 getResult(ResultSet,String)方法为例,该方法完成了异常处理等统一的工作,而与具体类型相关的 getNullableResult(ResultSet,String)操作则通过抽象方法交给具体的类型处理器实现。这就是典型的模板模式。

【代码8-5】

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

BaseTypeHandler<T>交给具体的类型处理器实现的抽象方法一共只有四个。在每个类型处理器都需要实现这四个方法。· void setNonNullParameter(PreparedStatement,int,T,JdbcType):向 PreparedStatement对象中的指定变量位置写入一个不为null的值;

· T getNullableResult(ResultSet,String):从 ResultSet中按照字段名读出一个可能为null的数据;

· T getNullableResult(ResultSet,int):从 ResultSet 中按照字段编号读出一个可能为null的数据;

· T getNullableResult(CallableStatement,int):从 CallableStatement中按照字段编号读出一个可能为 null的数据。

因为上面的抽象方法跟具体的类型相关,因此存在泛型参数 T。在每种类型处理器中,都给出了泛型参数的值。以 IntegerTypeHandler为例,它设置泛型参数值为 Integer。IntegerTypeHandler类的源码如代码8-6所示。

【代码8-6】

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

代码8-6中,IntegerTypeHandler处理的类型是 Integer,这表明其 getNullableResult方法给出的就是一个 Integer结果。

TypeReference类

43个类型处理器可以处理不同 Java类型的数据,而这些类型处理器都是 TypeHandler接口的子类,因此可以都作为 TypeHandler来使用。

那会不会遇到一个问题,当 MyBatis取到某一个 TypeHandler时,却不知道它到底是用来处理哪一种 Java类型的处理器?

为了解决这一问题,MyBatis 定义了一个 TypeReference 类。它能够判断出一个TypeHandler用来处理的目标类型。而它判断的方法也很简单:取出 TypeHandler实现类中的泛型参数 T的类型,这个值的类型也便是该 TypeHandler能处理的目标类型。该功能由getSuperclassTypeParameter方法实现,该方法能将找出的目标类型存入类中的 rawType属性。getSuperclassTypeParameter方法带注释的源码如代码8-7所示。

【代码8-7】

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

TypeReference 类是 BaseTypeHandler 的父类,因此所有的类型处理器都继承了TypeReference 的功能。这意味着对任何一个类型处理器调用 getSuperclassTypeParameter方法,都可以得到该处理器用来处理的目标类型。

类型注册表

定义了大量的类型处理器之后,MyBatis 还需要在遇到某种类型的数据时,快速找到与数据的类型对应的类型处理器。这个过程就需要各种类型注册表的帮助。

type 包中的类型注册表有三个:SimpleTypeRegistry、TypeAliasRegistry 和TypeHandlerRegistry。

SimpleTypeRegistry 是一个非常简单的注册表,其内部使用一个SIMPLE_TYPE_SET变量维护所有 Java基本类型。SIMPLE_TYPE_SET中的赋值是在 static代码块中进行的,如代码8-8所示。这说明在 SimpleTypeRegistry初始化结束后,就已经将所有的 Java基本类型维护到了 SIMPLE_TYPE_SET中。

【代码8-8】

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

TypeAliasRegistry是一个类型别名注册表,其内部使用 typeAliases变量维护类型的别名与类型的对应关系。有了这个注册表,我们就可以在很多场合使用类型的别名来指代具体的类型。TypeHandlerRegistry 是这三个注册表中最为核心的一个,数据类型和相关处理器的对应关系就是由它维护的。

在介绍它之前,我们先介绍 Java数据类型和 JDBC数据类型。假设某个对象中存在一个“String name”属性,则 name属性在 Java中的数据类型是String。

然而它在数据库中可能是 char、varchar,也可能是 tinytext、text 等多种类型。因此,Java数据类型和 JDBC数据类型并不是一对一的关系,而是一对多的关系。了解到这一点之后,我们在代码8-9中直接给出 TypeHandlerRegistry类的带注释的属性。

【代码8-9】

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

了解了 TypeHandlerRegistry的属性后,也可以猜测出如何才能拿到一个类型的类型处理器,实际就是一个两次映射的过程。

· 根据传入的 Java 类型,调用 getJdbcHandlerMap 子方法找寻对应的jdbcTypeHandlerMap后返回。· 基于 jdbcTypeHandlerMap,根据 JDBC类型找到对应的 TypeHandler。

例如,在给定 Java类型是 String,而 JDBC类型是 varchar后,就能唯一确定一个类型处理器。getTypeHandler 方法完成的就是这一过程,该方法带注释的源码如代码8-10所示。

【代码8-10】

通用源码阅读指导mybatis源码详解:type包 - 天天要闻

SimpleTypeRegistry、TypeAliasRegistry、TypeHandlerRegistry这三个类型注册表的存在,使 MyBatis 不仅可以根据类型找寻其类型处理器,而且还可以根据类型别名找寻对应的类型处理器。

本文给大家讲解的内容是通用源码阅读指导mybatis源码详解: type包

  1. 下篇文章给大家讲解的是通用源码阅读指导mybatis源码详解: io包;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持

娱乐分类资讯推荐

韦东奕短视频账号粉丝破2000万,“韦神”被申请注册为商标,律师解读 - 天天要闻

韦东奕短视频账号粉丝破2000万,“韦神”被申请注册为商标,律师解读

近日,有网友发现短视频平台有一名为“韦东奕”的账号,疑是韦东奕本人。据大皖新闻,经其家属证实,该账号确系韦东奕本人账号。6月8日,潇湘晨报记者发现,目前该账号粉丝已破2000万,仍在增长中,发布的唯一一条视频,点赞量已达1240万,其评论区变“高考许愿池”。其堂哥向媒体介绍,韦东奕开设账号的主要目的是为防止恶...
海报漫谈丨55岁本科毕业?人生没有“太晚”的剧本 - 天天要闻

海报漫谈丨55岁本科毕业?人生没有“太晚”的剧本

2025年6月的山西工商学院礼堂,聚光灯下,54岁的张计玲身着学士服,鬓角银丝在玄青袍的映衬下格外醒目。当校长为她拨穗正冠时——这位全校最年长的毕业生,终于为三十八年前的高考遗憾画上了句号。有人质疑“毕业即退休”,她却说:“追光不分早晚,心永远年轻。”自我赋能,而非逃离责任2021年,51岁的张计玲以高出二本线...
“这段关系已经结束”,特朗普警告马斯克! - 天天要闻

“这段关系已经结束”,特朗普警告马斯克!

‍‍当地时间6月7日美国总统特朗普警告前“政府效率部”负责人马斯克若资助民主党将面临“严重后果”两人近日的公开争执引发关注他们的架是怎么吵起来的?特朗普向马斯克发出警告还表示无意修复两人关系当地时间6月7日,美国总统特朗普表示,若特斯拉与SpaceX首席执行官埃隆·马斯克资助反对共和党预算案的民主党候选人,将...
今晚,李乃文唐旭张子贤做客《种地吧3》花式投喂十个勤天 - 天天要闻

今晚,李乃文唐旭张子贤做客《种地吧3》花式投喂十个勤天

江苏卫视劳作纪实互动节目《天猫×种地吧3》今晚播出第13期。节目中,少年们回到宁乡参观花猪养殖场,和小猪逗趣互动。众人本想按照计划洽谈花猪线下销售事宜,结果遇到一些阻碍。回到后陡门,李乃文、唐旭、张子贤来做客,不仅进门就干活,还狠狠地秀了一把厨艺带来一桌丰盛的晚餐,被花式“投喂”的勤天们香迷糊了……少...
演员孙俪,官宣喜讯 - 天天要闻

演员孙俪,官宣喜讯

6月7日,孙俪发长文称当天是自己和邓超第15周年结婚纪念日。孙俪称邓超送给自己的礼物是一对球拍,两人的生活越来越规律,“有空的时候送完孩子上校车,然后一起遛弯去喝杯咖啡看看路人聊个天~当我们有一方有工作时,对方也会好好守护这个家,不让对方担心。”2月8日,演员孙俪发文:2025愿我们能善良温柔面对每一个人……...