前言
最近工作不忙,突发奇想整理一下这些年的学习工作资料,偶然发现三年前记录的一篇mybatis的源码阅读笔记。当时刚刚入行,资历尚浅,还不知道怎么阅读源码。本想直接啃spring大部头,只能说是小马拉大车,根本带不动。彷徨很久没有目标,偶然从《深入浅出MyBatis技术原理与实战》这本书了解到mybatis源码相对简单,流程也相对容易理解,因此决定从阅读mybatis源码开始入门。本文是对当时笔记的梳理和分享,欢迎大家指正。
PS:本人非常建议没阅读过源码的同学,可以从阅读mybatis源码入门。因为他功能和结构比较简单,相比于JDK和Spring复杂的相互依赖,更适合入门。
mybatis运行概述
基本流程
mybatis的运行过程相对简单,总共分为三大个模块:
和一个串联全局的对象:Configuration
为什么说,Configuration对象是串联全局呢?如果各位阅读过mybatis源码,就应该有感觉,这个对象几乎无处不在:解析mybatis-config.xml文件的时候有,解析sql的时候有,接受返回并包装成bean的时候也有。再进一步观察Configuration对象里面存储的参数,几乎囊括了mybatis所有运行需要使用到的内容。配置如是否缓存、是否懒加载、是否生成主键、类型转换registry等等;sql执行相关如mappedStatement存储各个mapper.xml文件里的sql、resultMaps存储sql结果解析映射等等。后续关于源码的讲述也大多围绕着这个类展开。
配置的解析 —— SqlSessionFactoryBuilder
层次稍微有点深,在最开始先附上一个结构图,总共三层类,若干层方法嵌套:
首先就是SqlSessionFactoryBuilder,这个类相对比较简单:
图1 SqlSessionFactoryBuilder局部
进到parser.parse()方法,就可以看到下面的代码:图2 XMLConfigBuilder局部
各位看官看到这里应该就有点感觉,parseConfiguration方法里面的这些写死的参数,与mybatis-config.xml的dtd模板里人家给你配置的参数是完全一致的:
那么,这个类的实际作用就很明确了:通过加载mybatis-config.xml的inputSteam解析mybatis-config.xml文件,并生成Configuration对象用于后续使用。
我们先忽略别的配置(因为不大涉及到主流程),先重点关注mapperElement方法:
图3 XMLConfigBuilder局部
顾名思义,这个方法是解析resource包下所有配置sql的mapper.xml文件的。在早期的mybatis版本使用中,各个mapper.xml文件路径是需要配置在mybatis-config.xml文件里的,当然基本上都是用@MapperScan来扫描了。anyway,不管我们怎么配置了各个mapper.xml的文件地址,现在我们可以解析各个mapper.xml文件了。进入mapperElement方法:
图4 XMLConfigBuilder局部
图中的注释比较清楚了,进一步的解析逻辑在XMLMapperBuilder类里面:图5 XMLMapperBuilder局部
我们来看一看if里面的内容,拿configurationElement方法举个例子:图6 XMLMapperBuilder局部
看看里面写死的参数,是不是又很熟悉?俨然就是mapper.xml文件的dtd目标里限定的xml文件标签,相信使用过mybatis的同志们都知道是啥。那再往下看,例如resultMapElements方法:图7 XMLMapperBuilder局部
再例如buildStatementFromContext方法(方法太大了,只能截一部分。。。):图8 XMLMapperBuilder局部
至此,mybatis解析完成了所有的xml文件,形成了configuration对象放在了堆里面,等待着有请求访问mapper接口调用数据库查询并返回数据。
(未完待续......)