前戏
同样,学过springboot的人都知道,如果要整合什么框架,肯定要去找XXXAutoConfiguration。
需要框架源码的朋友可以看我个人简介联系我。 推荐分布式架构源码

在MybatisPlusAutoConfiguration中有如下,对SpringIoc容器进行注入sqlSessionFactory

在这个方法中,他会读取properties/yaml文件中的配置,和给Spring的上下文ApplicationContext进行设置内容。
最后他会调用factory.getObject()

刚开始,我们肯定是没有sqlsessionfactory的,所以肯定会执行afterPropertiesSet

在afterPropertiesSet中,他会调用buildSqlSessionFactory,来创建工厂

那好,我们已经到了SqlSessionFactory工厂的步骤,算是完成了前戏!!!
正文
buildSqlSessionFactory()是一个很长的方法,他总共有245行。
整体的目的是根据我们在上面前戏中,读取到的配置文件的要求创建对应的工厂。
那我们这次记录的重点是对sql语句的创建注入过程,那么他在buildSqlSessionFactory方法的哪里呢???
因为他很重要,所以他需要充足的条件,所以,在最后面。

在this.mapperLocations中有我们这次读取到的所有mapper.xml文件
上面,他就先从全局配置中获取,是否有自动刷新配置。
原本我们项目启动一次会加载指定目录下的mapper.xml文件。自动刷新配置就应该是设定有一个时机,他会再进行加载我们后加的mapper.xml文件。

然后,他就对加载到的所有的mapper.xml文件进行遍历读取
这里他通过XMLMapperBuilder来读取对应的mapper.xml文件,通过构造器给this.resource = resource附上值,然后执行bindMapperForNamespace
bindMapperForNamespace这里为这个mapper.xml绑定对应的Namespace,也就是对应的接口mapper类
之后在根据boundType(类对象Class),来加入到配置内容中addMapper
通过给mybatisMapperRegistry添加这个mapper内容
给mybatisMapperRegistry添加,就会对这个mapper进行解析
他会new MybatisMapperAnnotationBuilder()给传入配置内容和type(也就是大class对象)。进行初始化
拿到上面MybatisMapperAnnotationBuilder的对象,对用parse()方法,对我们上面传入的type(mapper接口类),和对应配置设置进行解析
那最关键的一步出现了,就是这个,就是这里parse()方法,可以通过这个Class对象,通过反射拿到他里面接口的方法
他会拿到这个mapper接口类,里面的方法,对应接口上面注解的信息,和对应的xml文件的内容
下面这个是mapper接口文件里面的方法,通过.xml配置文件写的sql
下面也是在mapper接口文件的方法,但是是通过注解的方法写sql的
这里的每一个方法就对应mapper接口中的一个方法

然后他会判断是否是桥接方法isBridge()
桥接方法是 JDK 1.5 引入泛型后,为了使Java的泛型方法生成的字节码和 1.5 版本前的字节码相兼容,由编译器自动生成的方法。我们可以通过Method.isBridge()方法来判断一个方法是否是桥接方法。

通过判断,他如果不是桥接方法,他就会执行parseStatement,去解析sql语句
getSqlSourceFromAnnotations(),会去对应这个方法的信息就获取对应的sql语句了!!!
先获取都头上的注解,判断是不是注解写的sql
然后他就能拿到注解上的这个具体写的sql,传入buildSqlSourceFromStrings进行解析
那他是怎么解析的呢?点进去看看。

<script脚本>
发现,他会对这个传入获取的sql进行判断,是否带有script脚本,来判断执行哪个逻辑
先看script脚本这个,他被包装了一层为XPathParser,然后传入createSqlSource
在createSqlSource中,他会再进行包装,包装成XMLScriptBuilder,然后就执行parseScriptNode解析里面的内容

里面具体是什么样子的呢???
解析里面的动态标签,判断他是否是动态的sql

解析他是否是动态sql,判断里面的node节点,也就是xml标签里面还有xml标签,就认为他是动态sql

判断完是否是动态sql,后就可以来用哪里SqlSource来封装他


没使用<script脚本>
回到之前的地方,如果他不是通过<script>脚本,那他就会走else的下面
通过PropertyParser的parse来解析,看到熟悉的
了
没
有
!
!
!
用
了没有!!!用{}来解析替换参数
在parse里面进行出现了过的${}进行拼接
那有个问题,他是如何进行判断是否是动态sql的呢???
上面解析处理完了${}后,new TextSqlNode(script),然后就进行isDynamic判断是否是动态sql
看上面,他是通过new一个DynamicCheckerTokenParser解析器,来去解析
在parse中

他是在这里调用handler的handleToken方法
发现这里给他设置了isDynamic为true,那就可以判断,他是根据是否有存在这样的关键字${}来判断他是否是动态sql
拿到这里就算解析完了一条sql语句,然后不断的循环解析
下面是一个例子
然后他就拼接封装给assistant.addMappedStatement
在addMappedStatement方法中,最后会封装成一个MappedStatement.Builder,加入到配置类configuration中
这个configuration,也就是Configuration接口,这里是MybatisConfiguration
最后我们看到了,他吧解析完的statement都加到了configuration中
这样子就有了所有需要执行的sql语句信息,mp中的基础的17个基本查询方法他是分散的在里面
我们自己写的自定义sql是如下形式
总结
这样子如上,我们看到了,他是不断的去读取mapper接口去反射回去对应的接口方法,获取头上的注解或者是.xml文件里面对应namespace名称空间的对应方法的xml标签,放入配置类中,并来获取组成遍历mapperLocations

然后在里面每一个都有一个methods,同样也是进行遍历,判断解析,是否是动态sql,是否是<script>脚本,还是row原生等

最后把他放到Mybatis配置类中的mappedStatements中


那么以上就是这次记录的全部内容,感谢你能看到这里!!! (•‾̑⌣‾̑•)✧˖°
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70006413/viewspace-2844023/ ,如需转载,请注明出处,否则将追究法律责任。