flydoging 2019-10-28
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
以上是一段摘自Mybatis中文官网的关于Mybatis的简要介绍,我个人觉得这短短的几句话将Mybatis的特性都给攘括在其中了。
经过一段时期关于Mybatis的认识,以及项目开发过程中的长期使用,我对Mybatis产生了些许兴趣,通过阅读一些博文以及视频,我决定也尝试一下Mybatis的源码阅读。但是这是我第一次对Mybatis源码进行阅读,同时也是我阅读的第一个成熟框架源码,源码阅读起来些许吃力。在阅读过程中,我希望通过随笔来对我的源码阅读过程进行记录,如果有不对的地方希望大佬能不吝赐教,多做批评!
阅读Mybatis源码需要对源码进行断点阅读,首先需要去下载Mybatis的源码,我下载的是Mybatis 3.5.3版本,地址是:https://github.com/mybatis/mybatis-3/archive/mybatis-3.5.3.zip
下载好源代码之后,解压源代码包,使用Idea导入源码,等待项目构建完成!
构建完成之后,出现以下的文件夹

接下来,编写一个Mybatis的启动小demo,用于对源码进行debugger(可参考Mybatis中文官网)
首先Mybatis需要一个xml的配置文件
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://ip:port/database?useUnicode=true&useSSL=false&characterEncoding=utf8"></property>
<property name="username" value="name"></property>
<property name="password" value="password"></property>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>编写一个测试的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.advance.learn.moudle1.mapper.UserMapper">
<select id="selectOneById" resultType="hashMap">
select * from user where id = #{id}
</select>
</mapper>接口文件
public interface UserMapper {
Map<String, Object> selectOneById(String id);
}编写一个启动类:
public static void main(String[] args) throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
System.out.println(userMapper.selectOneById("86f9428d286246cfa4d0f3f4cac5b720"));
}准备好相关事宜之后,开始对代码进行debug阅读了
第一步是读取配置文件xml,进入Resources.getResourceAsStream方法之后,看到如下结果

这一步只是一个简单的文件读取操作,下一步就是实例化SqlSessionFactoryBuilder类,然后调用build方法,获取sqlSessionFactory实例,看看代码:
SqlSessionFactoryBuilder类中包含了多个build方法,按照我们传的参数,可以知道代码进入以下方法
继续往下走


XMLConfigBuilder构造函数调用了parseConfiguration方法,将配置文件中的节点以及数据封装成Configuration对象,然后返回,这一步就可以得到我们的配置文件信息以及Mybatis给我们默认的一些配置,关于这一步,暂时不看,我觉得刚开始我需要先对Mybatis的大致执行流程有个初步概念,所以我继续往下走了

可以看到build方法最终是返回了一个DefaultSqlSessionFactory对象,这里还有一个SqlSessionManager对象,但是好像已经废弃了,所以我们看DefaultSqlSessionFactory对象


这里可以看出来,openSession方法最终返回了一个DefaultSqlSession对象,进入DefaultSqlSession,我发现他其中很有意思,小伙伴可以去看一看:


这里面包含了很多的默认方法,我发现他们都是从executor中获取的执行方法,所以我猜测,这个执行器里面应该是封装了jdbc的基本操作,我们后面再看这里
获取了SqlSession之后,就可以进入下一步操作啦!
由于时间限制,先记录这么多,下一篇我要探索一下Mybatis的一大神奇操作,为什么配置一个接口和一个xml文件,我们就能执行sql然后实现CRUD呢,这个问题我们下文继续探索,初次阅读源码,希望各位多多指教,多做批评!