mybatis配置文件的解析过程

在这里插入图片描述
1SqlSessionFactoryBuilder是mybatis与外界的接口.所以我们从这里出发跟踪
在这里插入图片描述
上面的代码是启动mybatis的一般用法.首先是获取inputstream流,这里调用的也是mybatis封装的类方法,其实都是调用的Class or ClassLoader类的getResourceAsStream方法来获取inputstream对象.mybatis只不过封装了下.然后调用SqlSessionFactoryBuilder的build方法开始解析xml.本文只关注XML的解析过程,把这个搞明白了.mybatis差不多明白了一半.截图代码如下:在这里插入图片描述
这个build就两句话,首先是创建一个XMLConfigBuilder对象,将必要的数据传过去在构造函数里面对对象进行初始化.这里注意一点XMLConfigBuilder构造函数里面会调用父类的构造函数,来对configbuilder对象进行初始化.然后就是parser.parse的解析过程了.build函数只不过是对解析出来的configbuilder进行了封装,新new了一个对象而已.
2.
在这里插入图片描述
代码开始进行了一次判断,判断之前有没有加载配置文件.有的话只是扔了个异常没有return.所以继续执行也是没什么问题的.首先从根节点加载configuration属性节点作为root节点,然后对root节点下的各自子节点属性进行解析.一个节点一个节点的来
3.首先是解析properties这个节点属性 在这里插入图片描述
如果配置文件里面存在这个节点,那么首先去获取其所有的子节点.这些子节点以<key,value>的形式成对出现.获取它们的值然后new一个property数组进行存放.最后赋值给defaults.当然如何property值很多.所以就搞一个外部文件配置通过resource或者url引起来.当然这两个属性不能同时存在.不然多出来的也是不会用到的.property读取完毕后,放在configuration里面存着.这个对象是存放所有属性的地方.
4settings属性
从配置文件中读取settings节点.这个节点里的数据也是以<key,value>方式存放的.但是对属性的范围是有限制的,其字符串只能是Configuration类的属性的名字中的某一个
如果这个属性里面有vfsImpl和logImpl属性,则解析它们然后设置到configuration里面去
5.typeAliases属性
在这里插入图片描述
这里首先判断是不是package,如果是则将这个package路径下面的所有class文件add到map.否则一项一项的读取配置alias和type增加到map中去,这里需要注意的一点是如果没有给出alias则会用class的名字作为key增加到map中去.所以为了避免出错最好统一要么都有别名要么都没有.
6.plugins属性在这里插入图片描述
这里插件是只作为拦截器进行处理的.我们自己定义的拦截器必须实现Interceptor接口定义.同时通过interceptor属性给出具体的class名字,通过反射生成拦截器对象.最后增加到configuration里面去.
7.objectFactory属性在这里插入图片描述
这个也是通过反射来的.代码很清晰不说了.
8.objectWrapperFactory属性在这里插入图片描述
通过反射填充对象
9.reflectorFactory在这里插入图片描述
通过反射填充对象
10.为configuratio填充属性在这里插入图片描述
这里有大量的configuration的属性用填充.我们从props里面读取的属性值大量为null,因为根本就没配置或者配置不完全
11environments属性.这个属性很重要是配置连接JDBC的,这里重点跟踪下在这里插入图片描述
首先读取default属性,然后再依次读取子节点数据.我们看到这里有一个id的读取.只有当id和default完全一样时.才会解析这个id节点之下的节点数据.所以如果我们有多个JDBC需要连接作为不同的工作模式.我们可以写很多个id配置,通过改变default就可以选择了.要注意一点这个id属性必须写在属性的首行
其次就是读取transactionManager属性.通过反射生成具体的对象.如果有子属性节点则读取set到对象.
再次就是读取dataSource属性.其后操作同上,这里给个配置截图.一看就明白在这里插入图片描述
这里transactionManager的属性值是JDBC,dataSource属性值是POOLED.那么反射生成的对象是什么类呢.这个在Configuration类的构造函数加载的时候被调用映射了在这里插入图片描述
到这里差不多都明白了.继续下一个属性读取吧.
12databaseIdProvider属性在这里插入图片描述
这里是通过读取属性值,通过反射生成对象.然后调用对象的getDatabaseId接口读取数据.参数是个面环境属性里面设置的datasource属性值生成的对象.这个databaseIdProvider没具体用过.不太清楚具体作用.
13.typeHandlers属性在这里插入图片描述
这个属性的解析跟typeAliases属性解析过程是一样的.都是最后注册到了map中
14.mapperElement这个属性是指出我们应用与mybatis具体通信接口的定义在这里插入图片描述
通过代码可知其有三种配置方式
1.配置resource
2.配置url
3.配置class
我自己示例用的是resource方式.我在这里也只跟踪这个的实现,其它的应该类似.要注意的一点是这三个属性同时只能存在一个,多个同时存在与代码的加载顺序相关,没有意义.
resource 加载方式:
1首先也是通过获取属性值得到路径,然后获取对应的inputstream.
2.通过指定参数生成XMLMapperBuilder对象
3.parse解析数据.看代码的实现在这里插入图片描述
首先看这个resource存不存在已经被加载的set里面.如果没有则增加进去并解析.configurationElement从根节点开始解析mapper代码截图如下在这里插入图片描述
1首先获取其namespace属性也就是名字空间.这个一定要有
2.获取cache-ref就是二级缓存,意味着多个Mapper共用这个chche-ref的缓存在这里插入图片描述
这里会先将两个名字空间分别作为key和value加入到map中去.然后再生成一个CacheRefResolver对象.然后查看这个cache-ref是不是在cache里,不在则将这个对象加入到linkset中去.具体干什么用的,还不清楚.以后看缓存的时候再看看.
3.获取cache属性.这个也是二级缓存与上面的区别是一对一的.代码截图在这里插入图片描述
首先获取这个cache的类名名字.然后用它获取获取Class.要注意的是这个类一定是Cache的子 类.
然后获取flush时间间隔. 获取大小. 获取是否是只读 获取是否为blocking 以及获取其它属性.
最后这些数据都被用来生成新的Cache.并且将这个Cache添加到configuration的Cache MAP里面.

4 mapper/parameterMap在这里插入图片描述
从根节点开始查找二级节点parameterMap.从这里的代码来看,就是读取各种配置属性值.要读取的属性是固定的.因此我们只能根本这里的代码配置指定的属性值.配置其它属性没用.最后这些属性值都保存在List里面.最终被保存到对象里面

5.mapper/resultMap 这个是个重要的配置.看到底是怎么映射的在这里插入图片描述
首先从读取type属性.这个值是一般是类的别名.当然从代码看type属性也可以有很多其它别名,也同样可以当type来用.它们是ofType resultType javaType.
其次:读到属性值后,根据这个属性值生成Class类.需要注意的是这个属性值一般是别名, 所以会先从map中找到别名对应的具体类名.然后再生成Class
再次:生成一个List来存放数据.接下来的addAll忽略因为传进来的list为空.然后就是对其下面的所有子节点进行一一读取.过程如下

首先对子节点名字进行判断.这里只跟踪最常见用法.所以直接到else处理id和result属性
然后通过buildResultMappingFromContext函数统一读取各种属性值截图如下在这里插入图片描述
这个for循环完成之后,子节点的属性值就处理完成了.
最后就是读取context的id属性.和其它属性,然后用所有这些读取的数据生成一个ResultMapResolver对象.至此处理完成.至于这些数据如何被使用,以后深入研究后,再写出来.目前不知道如何使用这些数据.载个配置图,比较明白些在这里插入图片描述
6. select|insert|update|delete 读取这些sql操作的数据
buildStatementFromContext(context.evalNodes(“select|insert|update|delete”));
这里需要注意的是context.evalNodes这个调用其实是生成xnode节点.而在XNODE的构造函数里面,已经对所传进来的XNode进行了解析.数据放在类的成员变量中.不需要再去对doc文档进行操作.截图如下在这里插入图片描述
所以所有的属性全部存放在attrubutes里面.而属性的内容则存放在body里面.这里Sql操作除了属性还有内容.给个示例在这里插入图片描述
所以Sql具体语句是保存在body里面的.下面来看sql的解析函数吧在这里插入图片描述
首先解析ID.也就是函数名.然后根据节点名判断sql语句类型.再其次就是判断配置里面没有启用cache.
然后 查看配置里面的函数接口有没有参数.如果有根据参数类型获取参数的具体class

后面还有很多其它参数的读取,不再逻列了.总之把所有可能的参数读取之后存放到对象中保存.
这里只关注配置文件的解析过程.对于怎么使用数据没有关注.后续将从接口调用的角度来看数据的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bruk_spp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值