![7b83ed37c32f6e5cbdbc1334bebe0f4c.png](https://i-blog.csdnimg.cn/blog_migrate/431860b0a167029bb3361a6c2bf6e5ae.jpeg)
修改一:
这篇文章写于2019年12月19日,今天是2020年2月6日,这几天我回过头来重新精读了mybatis源码,发现之前的理解还有些稚嫩,还有很多细节的地方没有写到,等过段时间有空我再重构一下文章。
---------------------------------------------------------------------------------------------
前言:
最近几天通过看源码来研究了一下mybatis的运行步骤,本篇文章以最基础的mybatis利用sqlSession操作数据库来讲解。我相信只要各位跟着我的节奏看完这篇文章就会对mybatis的运行步骤有个大体的认识(希望大家像我一样编写一个简单例子,然后跟着我的步骤看源码,不明白的地方debug)。这篇绝对是全网最详细的介绍mybatis运行原理的文章,当然如果你没有耐心看完的话,我也没任何办法,毕竟研究源码是一种枯燥的行为。如果你真的想去了解mybatis背后是怎么运行的,我相信这篇文章肯定会帮助到你。(文章如果有欠缺的地方,欢迎各位大佬指正)
第一部分:项目结构
user_info表:没什么好说的就3个字段
![3f380e706a058bccae7ea9f69844a995.png](https://i-blog.csdnimg.cn/blog_migrate/8a01413041fe5adaa8ee26cfb71fe674.png)
User实体类:
@Data
mapper:UserMapper 为根据id查询用户信息
public
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
mybaitis的主配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
数据库连接的属性文件:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mysql?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456
测试类:
@Component
结构图:
![a4c0ff7cf8eb4ae691382b67ac01de41.png](https://i-blog.csdnimg.cn/blog_migrate/6b8faf6ac22e929831833e0b29d7044f.png)
说明:我这虽然是个springboot项目,但是我并没有整个mybatis,依然用的最原始的方式,其中application.yaml中未配置任何东西,logback.xml为显示日志的配置。
第二部分:mybatis重要组件和运行流程图
- Configuration MyBatis所有的配置信息都保存在Configuration对象之中,配置文件中的大部分配置都会存储到该类中
- SqlSession 作为MyBatis工作的主要顶层API,表示和数据库交互时的会话,完成必要数据库增删改查功能
- Executor MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护
- StatementHandler 封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数等
- ParameterHandler 负责对用户传递的参数转换成JDBC Statement 所对应的数据类型
- ResultSetHandler 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合
- TypeHandler 负责java数据类型和jdbc数据类型(也可以说是数据表列类型)之间的映射和转换
- MappedStatement MappedStatement维护一条<select|update|delete|insert>节点的封装
- SqlSource 负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
- BoundSql 表示动态生成的SQL语句以及相应的参数信息
![da771a0f0456f34125f53b4c911164f8.png](https://i-blog.csdnimg.cn/blog_migrate/03028b132b7741b9e592ebc27f5e41bb.jpeg)
这个运行流程图先看不懂没关系,大致了解一下,下面会分析。
第三部分:初始化源码分析
首先我把测试类粘贴过来方便一点。
@Component
这是mybatis操作数据库最基本的步骤,前两行代码没什么好说的就是资源加载mybatis的主配置文件获取输入流对象,我们看第三行代码。
SqlSessionFactory
这行代码的意思就是根据主配置文件的流对象构建一个会话工厂对象。而且还用到了建造者模式--->大致意思就是要创建某个对象不直接new这个对象而是利用其它的类来创建这个对象。mybatis的所有初始化工作都是这行代码完成,那么我们进去一探究竟。
第一步:进入build方法。
public
可以看到会创建一个XMLConfigBuilder对象,这个对象的作用就是解析主配置文件用的。先说明一下,我们可以看出主配置文件的最外层节点是<configuration>标签,mybatis的初始化就是把这个标签以及他的所有子标签进行解析,把解析好的数据封装在Configuration这个类中。
第二步:进入parse()方法
public
XMLConfigBuilder维护一个parsed属性默认为false,这个方法一开始就判断这个主配置文件是否已经被解析,如果解析过了就抛异常。
第三步:进入parseConfiguration(...)方法
private
我们可以看出这个方法是对<configuration>的所有子标签挨个解析。比如常在配置文件中出现的settings属性配置,在settings会配置缓存,日志之类的。还有typeAliases是配置别名。environments是配置数据库链接和事务。这些子节点会被一个个解析并且把解析后的数据封装在Configuration 这个类中,可以看第二步方法的返回值就是Configuration对象。在这里我们重点分析的解析mappers这个子标签&