ITPub博客

首页 > 架构设计 > 软件结构 > mybatisplus的sql语句的创建过程之SpringCloud企业分布式微服务云架构快速开发平台

mybatisplus的sql语句的创建过程之SpringCloud企业分布式微服务云架构快速开发平台

原创 软件结构 作者:JIAN2 时间:2021-11-25 09:59:46 0 删除 编辑

前戏
同样,学过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/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
华为资深架构师,曾参与华为数据中心迁移解决方案!有需要了解分布式微服务电商源码的朋友可以+我 v ❤: haiwabbc2 , 10余年互联网研发行业经验!博客里面是个人的一点技术总结,希望能够帮助到更多的IT朋友成长!

注册时间:2021-09-06

  • 博文量
    1404
  • 访问量
    623057