美文网首页
Mybatis运行原理01-从xml配置到SqlSessionF

Mybatis运行原理01-从xml配置到SqlSessionF

作者: 布拉德老瓜 | 来源:发表于2021-03-06 21:31 被阅读0次

1.demo构建--我们做了些什么

首先建立一个demo,通过它来逐步认识mybatis内部是如何工作的。demo地址: https://mybatis.org/mybatis-3/getting-started.html

总结一下这个demo中我们做的事情吧: 

    1.定义一个mybatis-config.xml配置文件,配置的根节点为configuration,可配置的项有environments, 描述mappers信息的xml文件的位置,以及databaseIdProvider,typeHandler等信息。

    2.定义dao接口i.e.BlogMapper ,用来作为生成代理对象的模板。

    3.定义namespace与dao接口对应的mapper.xml

    4.开始使用mybatis完成数据的crud操作,如图。

a hello-world demo for mybatis

具体地:

        4.1 读取主配置文件mybatis-config.xml创建输入流is

        4.2 以is为资源创建SqlSessionFactoryBuilder这个建造器,没什么好说的,建造工厂用的,单一职责。

        4.3 构建SqlSessionFactory,也没啥好说的,就用来创建SqlSession对象。

        4.4 factory.openSession(),创建一个与数据库会话的sqlSession对象

        4.5 通过sqlSession对象获取到mapper的代理对象

        4.6 利用mapper代理对象实现对数据的操作,拿到结果集对应的java对象

        4.7 对结果集进行业务逻辑处理。

2.Mybatis做了些什么

简单来说,我们对mybatis的本身、操作数据的方法和方法对应的sql语句做了些配置,mybatis就按照预期完成了对数据的操作,并将结果集封装成了JAVA对象返回给了我们。那这个过程中它需要做哪些事情才能达到这样的效果呢?从我的角度来看至少应当做这些事情:

    1.解析配置文件

    2.将mapper配置的sql语句和方法对应起来,同时还得生成代理对象来执行方法。

    3.管理数据库连接、事务控制.etc

    4.sql语句的参数处理

    5.将结果集封装成指定的JAVA对象

3.debug看看吧

指定IO源-->读取数据流-->创建SqlSessionFactoryBuilder fb没什么可说的。

先看看fb是如何构建SqlSessionFactory的。

fb.build(InputStream is, ...)

该方法做了两件事情:

    1.通过指定的配置源,新建了一个xml解析器。xml解析器用于解析配置,然后生成一个Configuration对象,用来封装配置信息。可以用的配置源有:指定的输入流、系统环境配置以及properties文件。

    2.将Configuration对象作为build()方法的参数,构建SqlSessionFactory对象。

3.1 解析配置,创建Configuration对象

mybatis将解析配置文件并创建Configuration对象的工作交给了XMLConfigBuilder,该builder关联了configuration对象。解析分两步:

    3.3.1.解析xml文档树。

在配置文件中,<configuration>标签构成了文档树的一个节点。这里就是从这个标签开始,构建出一个节点。parser.evalNode()方法就是解析节点,在这里不讲。

XMLConfigBuilder.parse()

    3.3.2.调用parseConfiguraton()方法为configuration设置属性。(重要)

    在<configuration>内,有很多子标签,它们作为configuration的element。同样的,可以将其解析成一个个的节点,然后将其set到configuration对象的对应属性。先看一眼Configuration对象有哪些常见的属性吧。

Configuration类常见的一些属性

然后就开始解析配置文件中的子节点,并为Configuration对象设置属性了。这一步比较关键,因为后续的很多操作都离不开Configuration对象。

XMLConfigBuilder.parseConfiguration()

在这里以mappers为例,进去看个大概。

我们在configuration中指定mapper的方式有4种,如图。

(参考:https://www.cnblogs.com/dongying/p/4046488.html

指定mapper mappers节点解析

四种方式分别对应的解析方式说明:

1.指定resource,那么直接读取resource指定的xml文件,将其解析为mapper.

mapperParser.parse()

    之前XMLConfigBuilder完成了部分的Configuration对象属性的封装,现在他将这个对象作为参数传递给了XMLMapperBuilder来对Configuration对象的mapperRegistry属性进行完善。

    step1. XMLMapperBuilder去解析这个xml文件的/mapper标签,获取它的namespace,然后解析下面的parameterMap, resultMap, <sql ...>,存放到Configuration的对应map内,最后解析<select/insert/...>语句并存放到MappedStatements。如下图

configurationElement解析mapper.xml文件下的子标签

解析之后的statementMap如图:

mappedStatements

 step2. 标记该xml已被解析过。this.configuration.addLoadedResource(this.resource);

step3. 完成mapper与namespace的绑定。

        到这步的时候,实际上还只是解析出了mapper.xml的信息,但是mapper的代理对象还没创建呢,当然,这一步做完也没有创建出代理对象。但是不创建不要紧,总得给我个能创建代理对象的东西出来吧,到时候我根据mapper的namespace一查,就可以知道我该创建一个怎样的对象。那么给我个什么呢?想想创建对象需要干嘛?类加载,分配空间,实例化对象,初始化对象。那就简单了,给我一个这个类的Class对象好了。

        所以这一步要干的事情就是通过类加载器,完成类的加载的加载过程,获取它的类型。

mapper与namespace的绑定

    现在我知道他是什么类型了,我需要把他存起来吧,存哪里呢?mapperRegistry。所以config.addMapper()方法实际上把责任交给了mapperRegistry来完成类型的注册。

configuration.addMapper()

    mapperRegistry是一个hashMap,怎么就存一个Class对象type呢,这不对劲。实际上是以type:MapperProxyFactory(type)的形式存放的。这个proxyFactory的构造方法非常简单,就是将type作为属性放了进去。它的作用嘛,显然是等以后需要用到该mapper接口的代理对象时,用来创建代理对象。(这点等后面的文章细说)

mapperRegistry.addMappper(Class<T> type)

2.如果是指定包扫描的方式,获取包名,扫描包下的所有mapper,加载为class对象,存入configuration.mapperRegistry内。

指定package的方式

实际上到了最后,还是得遍历class数组,然后用mapperRegistry.addMapper(type)完成注册。

step4. 完成到目前为止还没有解析完的resultMap,statement...

原因是:resultMap的extends的没有解析,等待其余resultMap都解析完毕再次调用ResultMapResolver的resolve方法解析。此时若从configuration还得不到id为extends的ResultMap则忽略,因为parsePendingResultMaps中捕获了IncompleteElementException并啥也不做。ref:https://blog.csdn.net/shenchaohao12321/article/details/79841046

3.1.3 小结

本节描述了解析配置,创建Configuration对象的过程。其关键步骤在于创建Configuration对象,并为该对象完成属性赋值。

以mappers相关属性的设置为例,讲述了从xml文件解析mapper的parameterType、resultTyle、sql语句等信息,并与dao接口完成绑定的过程。

3.2 构建SqlSessionFactory对象

没什么好说的,直接调用构造方法

相关文章

网友评论

      本文标题:Mybatis运行原理01-从xml配置到SqlSessionF

      本文链接:https://www.haomeiwen.com/subject/nolsqltx.html