写这篇文章主要因为觉得自己总是只知其然,而不知其所以然!所以才写下这篇文章,其主要目的是帮助自己巩固加深所学习的知识。以后也会写更多这样的文章,希望能够帮到自己和其他人能够知其然,也要知其所以然。
Mybatis流程图
上图描述了Mybatis的一个整体流程图,包括从SqlSessionFactory的创建一直到Statment执行Sql,并且返回相关的结果,右边一部分是运行期间要使用到的额外对象。后边的分析也会围绕这个流程图进行分析,首先让我们进入到一个环节,创建SqlSessionFactory对象。
SqlSessionFactory
SqlSessionFacory通过SqlSessionFactoryBulid.build(InputStream in)创建,是整个Mybatis框架的入口,是个应用程序级别的对象,什么意思呢?就是整个应用期间只需要创建一个SqlSessionFactory对象,可以使用单例模式创建这个SqlSessionFactory对象。在与Spring整合之后,我们可以不用显示去创建这个对象,Spring会帮我们进行创建维护。以下是对SqlSessionFactory的创建:
1 | public class SqlSessionFactoryBuilder { |
从上述源码中,我们发现SqlSessionFactory中有个非常重要的对象Configuration,它的作用非常的打,维护了mybatis-config.xml的配置信息、Mapper.xml转换成的MapperStatement集合信息、resultMap转换成的ResultMap集合信息、Cache缓存集合信息等。那到底XMLConfigBuilder类是怎样将字节流转换为Configuration对象呢?下边源码较多,请大家做好准备……
我们在解析将字节流转换为Configuration对象之前,先看下Configuration对象都存在哪些变量,这样子我们在后边的解析都会知道做了什么,什么方法是给Configuration那个变量设置值。
1 | public class Configuration { |
首先我们先看下上述中parser.parse()方法:
1 | public Configuration parse() { |
上述方法即是通过XPathParser实例去解析configuration根节点信息,因为本文主要是将Mybatis的相关原理,则不去介绍XPathparser的用法,如果大家想要了解,可以看下源码或者去看下这篇文章[]。当然,如果后边有机会,我也会写一篇关于这个XPathParser的源码解析以及用法。
继续我们上述源码的解析,发现调用了parseConfiguration()方法,具体的源码如下:
1 | private void parseConfiguration(XNode root) { |
看到上述代码,我们会发现其实就是在解析XML文档,然后在设置到Configuration对象中,没有什么过多分析的内容,我们就分析下其中最重要的mapperElement(root.evalNode(“mappers”))方法。具体的源码如下:
1 | //解析mybatis.xml配置的mapper元素的配置 |
通过上边的代码我们发现上述代码是获取mapper元素中的resource/class/url属性,然后创建XMLMapperBuilder对象来解析mapper元素属性所对应的数据源(mapperParser.parse()),然后构造MapperStatement对象。接下来,我们继续看mapperParser.parse()方法:
1 | public void parse() { |
上边的代码发现如果未加载解析过数据源,则先解析Mapper.xml数据源,并且将该命名空间添加到configuration对象中,如果已加载过数据源,则将结果集对象、缓存对象添加到MapperBuilderAssistant中,最后将其解析为MapperStatement对象添加到Configuration对象中。
configurationElement(parser.evalNode(“/mapper”))方法就不在这里做解析了,主要是解析其中的各个元素将其添加到MapperBuilderAssistant对象中。其中最主要的是parsePendingStatements()方法,该方法中调用了XMLStatementBuilder.parseStatementNode()方法,将其封装为MapperStatement对象。接下来,我们主要看下Mybatis是如何构造MapperStatement对象:
1 | public void parseStatementNode() { |
上述的代码获取了Mapper.xml中关于insert、update、delete、select中元素的属性,并在最后调用了builderAssistant.addMappedStatement方法,分析到这里,我们已经很接近MapperStatement对象创建并将其添加到configuration对象中,让我们在分析最后一段源码:
1 | public MappedStatement addMappedStatement( |
这段代码我们可以看到主要是将获取到的各个属性设置到Mapperstatement对象中,使用了建造者模式进行最后的创建。其中还涉及到了输入参数该取何值的情况,如果设置parameterMap,则取parameterMap的,如果未设置parameteMap设置了parameterType,则将其解析为ParameterMap类型,将其添加到MapperStatement对象中。
分析到这里,Mybatis的SqlSessionFactory的创建就分析完了,其中的代码比较多,解释比较少,因为我觉得上边的代码大部分都能看得懂,当然其中还有一些代码因为篇幅等原因我没有在这个章节分析,例如:SqlSource的创建、Xml的解析等,这些会在后续的Mybatis源码解析中讲解,请大家继续关注。
最后做一个总结,SqlSessionFactory的创建主要是通过SqlSessionFactoryBuilder.build(Stream in)方法创建,其中包含一个至关重要的对象Configuration对象,Configuration主要包含了Mabatis.xml中的配置信息、Mapper.xml转换成的MapperStatement集合、ResultMap集合、ParameterMap集合等,而MapperStatement对象包含了每个SQL的相关配置信息。在之后的SqlSession的查询,修改中,Configuration和MapperStatement对象起着至关重要的作用,所以大家还是有必要了解这块的内容的。最后,祝大家的编程水平节节高,工资翻番!