目录
一、Mybatis总体架构图
1.总体架构流程图
2.主要类UML类图
2.1 存储解析内容的对象
2.2 各类handler
2.3 各种Builder构造器
2.4 组件注册中心
2.5 SqlSession部分
3.核心类Configuration结构
3.1 configuration.xml配置文件
3.2 mapper.xml配置文件
Mybatis相关传送门:
- (三)Mybatis持久化框架原理之启动源码分析;
- (四)Mybatis持久化框架原理之运行源码流程;
- (五)Mybatis持久化框架原理之MapperFactoryBean方式和Spring集成。
一、Mybatis总体架构图
1.总体架构流程图
总体架构流程图如下:
结构分析:该图大致可以分为三个部分:
- 从入口进入到解析configuration.xml文件分为一部分。这部分主要是框架的入口,以及完成读取解析mybatis的配置文件并返回Configuration对象功能;
- 完成解析mappers配置引入的mapper.xml文件的解析,并获得诸如ResultMap、Sql以及几种不同的数据库处理标签对象;
- 最后一部分便是使用前面获得的配置及对象去实际操作数据库,即从SqlSessionFactory对象生成SqlSession对象,再获得Mapper的代理对象去查找数据库。
总体流程:
- 通过mybatis自己封装的Resources类读取mybatis-config文件,其原理是调用了classLoader的getResourceAsStream方法;
- 调用SqlSessionFactoryBuilder的build方法获得解析后的XML文件parser对象;
- 对parser对象调用parse方法进行解析,先获得configuration节点信息;
- 解析configuration中的子节点,如最常用的properties、typeAliases、environments和mappers子节点,接着调用各自对应的解析方法,解析各个节点信息;
- 其中必不可少的两个节点分析为environments和mappers节点信息的分析,environments节点可以分析出事务工厂TransactionFactory和数据源工厂DataSourceFactory,并从其中构造出数据源和事务管理,解析environments时会默认把第一个environment当成第一个数据源配置,如果后面有ID相同,则使用相同的ID替换原来的数据源配置;mappers节点解析主要是为了解析出sql、resultMap等节点信息,并且将其封装成各种节点,保存在Configuration中,并在最后返回Configuration实例,以便后续使用;
- 利用build方法获得Configuration对象后,利用DefaultSqlSessionFactory类的构造方法实例化DefaultSqlSessionFactory对象;
- 利用openSession方法获得一个封装了事务以及SQL执行器的默认DefaultSqlSession对象,其中包含了各种select、update等的方法;
- 使用SqlSession对象获得mapper的代理对象,其对象封装了完整的sqlSession以及各种声明的数据库调用方法;
- 调用mapper代理类相应的sql方法,完成数据库查询。
2.主要类UML类图
主要类UML类图如下所示:
图片说明:看起来就很复杂,其中只放出了关键的类,一些可以忽略的中间类暂时没有放进去。看完大致结构流程图,对于Mybatis的主要UML类图应该可以更好的理解,不同于框架流程图,UML类图可以大致分为五部分:
2.1 存储解析内容的对象
其对应的结构组成图如下:
可以说是组成Mybatis框架的基本盘,诸如UML类图中的SqlNode、ResultMap、ParameterMap、MappedStatement、XNode、JdbcType和SqlSource这些,像XNode存储的便是XML文件解析后的标签内容,SqlSource存储的则是将要运行的Sql及其参数对象,SqlNode则是if、set、where等动态标签的接口,ResultMap和ParameterMap这些的作用便不用做过多介绍了。
2.2 各类handler
其对应的结构组成图如下:
这部分的作用便是对mybatis获得的解析后内容的处理,如参数、参数类型、结果、操作Sql和查询数据结果等对应的ParameterHandler、TypeHandler、ResultHandler、StatementHandler和ResultSetHandler这些处理类。
2.3 各种Builder构造器
其对应的结构组成图如下:
BaseBuilder是各类构造器的共同父类,其子类一共有六个,分别的作用如下:
- MapperBuilderAssistant:从名字可以看出来,这是解析Mapper.xml文件时的助手类,即主要的解析逻辑不在这个类中实现,这个类只是一个中转站,负责调用诸如ResultMap和ParameterMap以及MappedStatement这些类的构造器;
- SqlSourceBuilder:用来解析生成SqlSource的构造器,SqlSource的作用便是保存运行Sql以及其对应参数,或者对Sql的一些通配符进行替换等操作,像if和where这些动态Sql就是在DynamicSqlSource对象中完成拼装获取的;
- XMLConfigBuilder:对mybatis的配置文件configuration.xml进行解析的构造器,可以看成Mybatis最外层的构造器;
- XMLMapperBuilder:对mapper.xml文件进行真正解析的构造器,对不同的标签进行解析和识别,并调用MapperBuilderAssistant中的方法搭配使用,解析获取mapper.xml文件中标签对应的对象;
- XMLScriptBuilder:对Sql脚本语句进行解析的构造器,其作用便是确定Sql脚本的类型,如果是动态Sql,则搭配SqlNode和NodeHandler来进行解析和拼装,如果是静态或者原生的Sql,则直接使用对应的SqlSource封装并解析;
- XMLStatementBuilder:对select、insert、update和delete这四种实际调用的Sql标签进行处理的构造器,在这里面会完成include、if、set和selectKey等标签的解析和拼装,也会解析标签中缓存相关的配置,最终搭配MapperBuilderAssistant生成MappedStatement对象。
2.4 组件注册中心
其对应的结构组成图如下:
Mybatis有很多配置内容和对象都很多且分散,因此需要对应的注册中心来管理这些,如前面所说的TypeHandler因为类型很多,需要TypeHandlerRegistry来管理,而获取到的mapper接口则需要MapperRegistry来管理等。
2.5 SqlSession部分
其对应的结构组成图如下:
这部分包括SqlSession、SqlSessionFactory以及Executor等,这部分的功能便是根据前面的数据对象等来传入Jdbc获取数据,并使用对应的处理器对其进行处理,从而实现多种数据形式的获取。
3.核心类Configuration结构
从上面流程图也可以看出来Configuration这个对象是十分重要的,实际上确实是这样,它包含了Mybatis解析获得的所有对象类型,我们可以大致看一下其结构对象组成图:
接下来分别说说configuration.xml和mapper.xml两个文件解析出对应内容存储的对象。
3.1 configuration.xml配置文件
我们使用的时候这个XML文件中一共有十一种按不同的标签类型,接下来按先后分别说明一下,需要注意的是,XML文件中要求的先后顺序就是Mybatis处理标签的顺序,即以下顺序:
- properties:用来将另外properties文件中的配置属性加入到Configuration对象的variables对象中,以便后续使用,需要注意的是只能有一个这样类型的标签,并且先读取resource属性,后读取url属性,且两者只能同时使用其中一种;
- settings:Mybatis框架的运行配置,诸如logImpl、cacheEnabled和defaultExecutorType这些常见的配置都是在这个标签中声明子标签完成的;
- typeAliases:用来手动添加一些类的别名,如有个XXX.XXX.XXX.NornalStudent类,便可以使用student来作为其类的别名;
- plugins:用来添加插件,可添加多个,内部的原理是拦截器链;
- objectFactory:确定objectFactory的类型,只能同时存在一个;
- objectWrapperFactory:同objectFactory;
- reflectorFactory:同objectFactory;
- environments:用来配置数据源和事务管理器,能有多个配置,但只会取其中的一个;
- databaseIdProvider:顾名思义,确定刚配置的数据源名称;
- typeHandlers:添加一些额外类型处理器,如自己实现了custom类型的类型处理,则在这个标签里面添加进去即可;
- mappers:多种配置方式,但大体上可分为两者,一种是直接确定mapper的接口包位置,然后将包下的添加进mapperRegistry对象中;第二种是决定单一的接口类或者指向一个XML文件,如果指定了单一的接口类,则直接添加进mapperRegistry对象中,如果是指向一个XML文件,则需要调用XMLMapperBuilder去解析这个XML文件,从而获得它的标签内容。
3.2 mapper.xml配置文件
如果configuration.xml文件中mapper标签配置的是resource或者url方式,则会对xml中的以下几个标签内容进行解析:
- namespace:当前XML在解析时存在的唯一标识,对应与Mapper接口的路径及名字,因此绝对是唯一的;
- cache-ref:顾名思义,cache缓存引入,如果想要和另外的Mapper共享一个缓存,则把另一个Mapper的命名空间引过来即可;
- cache:缓存,当前mapper的缓存配置,如使用缓存的类型、方式及size等;
- parameterMap:自定义的参数映射,可对应mapper接口方法中的参数,在Mybatis内部会生成ParameterMap类型的对象;
- resultMap:自定义的结果返回类型,对应mapper接口方法返回值,可与从数据库查出来的字段形成映射关系并返回,会在Mybatis中生成ResultMap对象并保存;
- sql:自定义的一些SQL片段,直接读取出来保存在sqlFragments集合中,以便后续根据id获取节点信息使用;
- select|insert|update|delete四种类型节点的读取:重头大戏,会使用XMLStatementBuilder对象去解析XML标签,并最终生成MappedStatement对象保存在mappedStatements对象中,这里面包含了前面获得的ResultMap、ParameterMap以及生成的SqlSource对象等,可以说Sql语句需要的东西这里面都有。