美文网首页
mybatis源码分析二(加载映射文件)

mybatis源码分析二(加载映射文件)

作者: 为梦想前进 | 来源:发表于2019-10-11 15:58 被阅读0次

    最近一直再看mybatis源码,稍有心得,这里分析下mybatis是如何工作的,上一节分析了配置文件的解析,今天来分析下,mybatis加载映射文件,咱们就先从映射文件的加载开始分析,进入主题

    这里是一个比较简单的映射文件,接下来,咱们就开始进入到源码,来一起看看mybatis到底是怎么加载映射文件的

    我这里引入的是3.4.5的版本

    接下来我们一起进入正题

    首先,当我们启动项目的时候,这里强调一下,暂时不分析sqlSession的构建和sqlSessionFactory的创建,以及数据源,默认这些对象已经加载完毕,加载完之后,需要加载映射文件,就会进入XMLMapperBuilder的parse方法

    /**

    * 分析configurationElement这个方法,进入这个方法,大家有没有一种特别熟悉的感觉,咱们在映射文件中配置的标签在这里都出现了,

    * cache-ref对应<cache-ref namespace="ale"></cache-ref>标签

    * cache对应<cache/>标签

    * resultMap对应<resultMap></resultMap>标签

    * sql对应<sql></sql>标签

    * 下面就是crud标签都是在这里一一对应的

    * parameterMap已被废弃!老式风格的参数映射。更好的办法是使用内联参数,此元素可能在将来被移除。文档中不会介绍此元素

    * ,咱们从cache结点开始往下一一分析下

    1.1先来看cache结点解析

    首先是会看到获取cache结点的各个属性,如果没有配置这些属性,他就会取默认值,每个属性都设置了默认值

    一起来看下useNewCache方法

    1.2cache-ref结点解析方法

    cache-ref的解析比较简单,大概就是这样,可能中间也有还没有搞定的地方,像unresolvedCacheRef =true;unresolvedCacheRef =false;先设置为true,然后设置为false,这段我也是没有理解啊,

    1.3resultMap结点解析

    * 接下来,我们重点来看下resultMap结点的解析,这个可是比较重要,我们来看一段官网的解释

    * resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,

    * 并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,

    * 一份 resultMap 能够代替实现同等功能的长达数千行的代码。

    ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了

    好了,一起来分析下源码吧

    结点解析全部放在了resultMapElement中,

    上面的逻辑大致就是

    1:获取 <resultMap> 节点的各种属性

    2:遍历 <resultMap> 的子节点,并根据子节点名称执行不同的逻辑

    3:构建 ResultMap 对象

    4:若构建过程中发生异常,则将 resultMapResolver 添加到 incompleteResultMaps 集合中

    接下来一起看看是如何构建requestMapping的

    第一步:解析javaTyp类型,

    第二步:获取typrHanle实例

    第三步:解析column

    第四步:构建ResultMapping

    咱们继续往下,分析下resultMap对象的构建过程

    我们可以看到构建resultMap的对象的过程是ResultMapResolver交给MapperBuilderAssistant来完成的

    代码比较长,大家可以跟着源码一起看下来,其实也不难,这里定义的5个集合中存储的数据,咱们一起来看看官网的介绍

    /**

    * mappedColumns  用于存储 <id>、<result>、<idArg>、<arg> 节点 column 属性

    * mappedProperties    用于存储 <id> 和 <result> 节点的 property 属性,或 <idArgs> 和 <arg> 节点的 name 属性

    * idResultMappings    用于存储 <id> 和 <idArg> 节点对应的 ResultMapping 对象

    * propertyResultMappings  用于存储 <id> 和 <result> 节点对应的 ResultMapping 对象

    * constructorResultMappings  用于存储 <idArgs> 和 <arg> 节点对应的 ResultMapping 对象

    */

    1.4sql结点解析

    * 判断是否存在DatabaseId属性,如果不存在,就赋值为null执行sqlElement的重载方法,这里可能有好多人还不知道DatabaseId的作用

    * 咱们一起看一下这个id到底是干嘛的

    * MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。 如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。

    * 为支持多厂商特性只要像下面这样在 mybatis-config.xml 文件中加入 databaseIdProvider 即可.

    * 也就是说当你的项目中需要同时支持不同的数据库的时候,在需要使用到的sql语句中配置他即可,如果好多的sql语句怎嘛办,

    * 咱们可以配置个全局的,然后引入就可以了,像这样

    *      `id`,`name`,`money`,`createTime`,`updateTime`

    *      `id`,`name`,`money`,`createTime`,`updateTime`

    *  然后在需要的地方引入这个sql即可

    1.5sql语句解析

    其他的咱们就不分析了,主要本人还么有理解,咱们主要分析下解析sql语句的源码

    * createSqlSource有两个实现类

    * 1:RawLanguageDriver:从3.2.4开始,默认的XML语言能够识别静态语句*并创建{@link RawSqlSource}。

    * 因此,除非您出于任何原因要确保没有任何动态标签,否则无需使用RAW

    * 2:XMLLanguageDriver

    * 所在咱们常用的是XMLLanguageDriver

    SQL 语句的解析逻辑被封装在了 XMLScriptBuilder 类的 parseScriptNode 方法中。该方法首先会调用 parseDynamicTags 解析 SQL 语句节点,在解析过程中,会判断节点是是否包含一些动态标记,比如 ${} 占位符以及动态 SQL 节点等。若包含动态标记,则会将 isDynamic 设为 true。后续可根据 isDynamic 创建不同的 SqlSource

    首先进入parseDynamicTags方法

    加载各个结点,handleNode有不同的实现类,用来加载不同的结点

    大家看名称有么有觉得很耳熟,不同的动态结点封装在在不同的方法中实现,我们器看一下where结点的解析

    * sql已经解析结束,big存在于sqlSource中,

    * 构建 MappedStatement 对象,并将该对象存储到

    * Configuration 的 mappedStatements 集合中,

    映射文件的解析过程就就结束了,但是现在只是解析完了这些,咱们每次不都是通过接口实现查询,然后返回结果的吗,现在执行下一个步骤,丙丁借口

    回到原来的XMLMapperBuilder,分析映射文件的解析过程,接下来走最后一步,为命名空间绑定映射关系

    下一期,咱们一起分析下mybatis的sql语句执行流程过程,今天就先到这里,  thanks

    相关文章

      网友评论

          本文标题:mybatis源码分析二(加载映射文件)

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