Mybatis源码阅读之数据库连接

前面我介绍了SqlSessionFactory和SqlSession的创建,感兴趣的童鞋可以看看我写的这两篇博客:

mybatis源码阅读之SqlSessionFactory创建

Mybatis源码阅读之SqlSession创建

最近接着在看Mybatis的源码,想知道Mybatis是如何对数据库进行操作的(最底层当然还是回归JDBC),这里做个学习笔记,也想跟大家分享下:

执行代码如图1:

Mybatis源码阅读之数据库连接_第1张图片

图1.

通过sqlSession.selectList(“xxxx”)来一步步跟踪Mybatis是如何完成对数据库的操作的。之前的文章有说到,SqlSession是个接口,创建的时候使用的是DefaultSqlSession。图2是自己断点SqlSession获得的信息:

Mybatis源码阅读之数据库连接_第2张图片

图2.

我在mybatis-config.xml中的配置如图3:我选择的TransactionManager类型是JDBC,数据源是PooledDataSource。这也就解释了图2中的executor的Transaction为什么是JdbcTransaction,JdbcTransaction的数据源为什么是PooledDataSource。
Mybatis源码阅读之数据库连接_第3张图片

图3.

我之前的文章已经说明了JdbcTransactionFactory和PooledDataSource是如何创建的。
new SqlSessionFactoryBuilder().build(InputStream)
–> XMLConfigBuilder.parse()
–>XMLConfigBuilder.parseConfiguration(XNode root)
Mybatis源码阅读之数据库连接_第4张图片

图4.

Mybatis源码阅读之数据库连接_第5张图片

图5.

mybatis是如何获取到配置文件的用户名和密码,然后连接获取数据库连接的呢?我们来看一下XMLConfigBuilder.transactionManagerElement(XNode context)和XMLConfigBuilder.dataSourceElement(XNode context)

Mybatis源码阅读之数据库连接_第6张图片

图6.

看看DataSourceFactory的Properties props = context.getChildrenAsProperties();做了哪些操作
Mybatis源码阅读之数据库连接_第7张图片

图7.

XNode.getChildren()中有一句children.add(new XNode(xpathParser,node,variables)),这里的variables是一个Properties,这个variables值的初始化是通过解析mybatis-config.xml的properties标签得到的。如下图,先加载properties标签下的property,再加载properties文件中的属性,最后,判断原来是否存在一些属性,是的话就两个合并返回,否则直接返回。
Mybatis源码阅读之数据库连接_第8张图片

图8.

再来看看DataSourceFactory的factory.setProperties(props);做了哪些操作
进行赋值前:
Mybatis源码阅读之数据库连接_第9张图片

图9.

进行赋值后:
Mybatis源码阅读之数据库连接_第10张图片

图10.

再回去看图2,session.selectList(“xxx”)实际上调用的是DefaultSqlSession.selectList(“xxx”);这里的executor的实现类是CachingExecutor。
Mybatis源码阅读之数据库连接_第11张图片

图11.

调用的CachingExecutor.selectList()方法如图12,先查看缓存中是否有值,有的话从缓存中获取,没有的话查询数据库。这里的delegate属性调用的是SimpleExecutor,SimpleExecutor继承了抽象类BaseExecutor。
Mybatis源码阅读之数据库连接_第12张图片

图12.

调用父类BaseExecutor.query()方法如图13,
Mybatis源码阅读之数据库连接_第13张图片

图13.

调用父类BaseExecutor.queryFromDatabase()方法如图14,BaseExecutor是个抽象类,doQuery()调用的是实现类SimpleExecutor的方法。
Mybatis源码阅读之数据库连接_第14张图片

图14.

调用子类SimpleExecutor.doQuery()方法如图15,
Mybatis源码阅读之数据库连接_第15张图片

图15.

调用子类SimpleExecutor.prepareStatement()方法如图16,
Mybatis源码阅读之数据库连接_第16张图片

图16.

调用父类BaseExecutor.getConnection()方法如图17,从图2中可以看到transaction的实现类是JdbcTransaction。
Mybatis源码阅读之数据库连接_第17张图片

图17.

在创建SqlSession的时候调用了DefaultSqlSession类的openSessionFromDataSource()方法,而transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit)调用了JdbcTransactionFactory的方法来创建JdbcTransaction。见图18和图19。
Mybatis源码阅读之数据库连接_第18张图片

图18.

Mybatis源码阅读之数据库连接_第19张图片

图19.

调用的数据源是在mybatis-config.xml配置的PooledDataSource。
Mybatis源码阅读之数据库连接_第20张图片

图20.

PooledDataSourceFactory的创建图6说明了。PooledDataSourceFactory继承了UnpooledDataSourceFactory,PooledDataSourceFactory的无参构造函数初始化了属性dataSource的值为PooledDataSource,而PooledDataSource的无参构造函数初始化了属性dataSource的值是UnPooledDataSource。见图19和图20。加载顺序是:PooledDataSourceFactory.dataSource–>PooledDataSource.dataSource–>unPooledDataSource.dataSource。
Mybatis源码阅读之数据库连接_第21张图片

图21.

Mybatis源码阅读之数据库连接_第22张图片

图22.

PooledDataSource的getConnection()方法,调用UnpooledDataSource的用户名和密码连接数据库。
Mybatis源码阅读之数据库连接_第23张图片

图22.

你可能感兴趣的:(mybatis)