mybatis源码调试

1,887 阅读2分钟

搭建源码环境

mybatis源码搭建非常简单,克隆代码到本地,使用idea打开工程等待编译完成

代码地址; github.com/mybatis/myb…

tag : mybatis-3.5.3

其他:java 、maven、mysql

调试代码前

对于mybatis的架构等方面的知识,大家可以自行查询,这里主要是我自己的调试过程

  • mybatis自带完整的测试用例,可以直接使用测试代码进行debug,本次调试就是使用自带的测试用例进行的,目录结构如下:

修改mybatis-config.xml文件,使用自己的实际配置即可

以调试模式运行 org.apache.ibatis.autoconstructor.AutoConstructorTest.fullyPopulatedSubject即可。

调试代码

----------------------------------初始化阶段-------------------------------------------

开始阶段,mybatis肯定要首先初始化mybatis的上下文环境,以下是初始化过程的时序图,包含了主要的类的方法

主要的函数调用顺序在时序图中已经标明,不再赘述,

----------------------------------执行阶段-------------------------------------------

初始化结束后,可以进行数据库操作的调用
从开始调用到从数据库中查询出数据的调用堆栈

关于sql

通常,我们使用myabtis框架的时候,会把sql语句写在mapper.xml中; 这个测试用例中,把sql语句放入了注解中,(原理是相同的)

关于配置文件

因为我们平时使用的基本都会使用数据库连接池+事务的方式,所以也修改了配置

代码调试入口

其中,setUp()函数中的 try 部分,属于mybatis初始化上下文部分,可以参考上边的时序图,

这里,我们主要关注 fullyPopulatedSubject()函数

首先是fullyPopulatedSubject() 的内部调用,(缩进表示调用的层级关系)

----------------------------------遇到的疑问-------------------------------------------

由于我们配置了数据库连接线程池,这就需要管理单个连接状态,单个状态的管理类是PooledConnection,那mybatis是在何时认为可以把一个连接从active状态置为idle状态呢

根据源码,当java.sql.Connect.close()被调用时,mybatis认为可以把一个连接有active状态置为idle状态

问题是:java.sql.Connection.close()什么时候会被调用呢?

答案:java.lang.AutoCloseable

java.lang.AutoCloseable的出现是为了更好的管理资源,准确说是资源的释放,当一个资源类实现了该接口close方法,并且这个资源对象是在try-with-resources语法中创建的,那么资源类被释放时,JVM会自动调用close()方法

例如, sqlSession

SqlSession 接口继承了java.lang.AutoCloseable, 并且SqlSession的实例对象是在try(...)中被创建的,所以当fullyPopulatedSubject() 执行结束后,SqlSession对象会被JVM释放,此对象的close()方法就会被调用,最终会调用到PooledConnection的invoke方法,实现把一个连接从active状态置为idle状态。

至此,调试结束。