美文网首页MyBatis学习(完)
MyBatis源码分析(03)SqlSession和Execut

MyBatis源码分析(03)SqlSession和Execut

作者: 郭艺宾 | 来源:发表于2019-08-01 22:27 被阅读3次

    前面的内容在源码中查看了SqlSessionFactory对象的整个构建过程,就是下面这一行代码:

    SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);

    下面我们来看一下SqlSession对象的构建过程,也就是下面这一行代码:

    SqlSession session = sqlSessionFactory.openSession();

    首先来看我们的起点,也就是第一步:

    1、SqlSession session = sqlSessionFactory.openSession();

    这一步也就是从sqlSessionFactory对象中获取SqlSession对象,那么是如何获取的呢?我们来打断点,然后继续debug:

    SqlSessionFactory类是个接口,前面大家都知道,这里面真正创建的对象是DefaultSqlSessionFactory对象,那么我们来进入真正实现的地方:

    1、SqlSession session = sqlSessionFactory.openSession();

    2、org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()

    在这个方法里面,真正调用的是openSessionFromDataSource方法,这个方法有三个参数,第一个是获取默认的ExecutorType,这个是什么呢?进入方法看到返回了一个属性:

    这个属性的默认值是:

    这是从枚举类里面获取的SIMPLE值,我们进入枚举类看一下:

    这里面定义的三个常量是我们SQL执行器的三个类型,分别是简单类型,复用类型,批量类型。如果不指定,那么默认就是简单类型。这就是openSessionFromDataSource方法的第一个参数,可以看到其他两个参数默认是空,下面我们进入这个方法查看:

    1、SqlSession session = sqlSessionFactory.openSession();

    2、org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()

    3、org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource

    从代码逻辑可以看出,进入方法后,先拿到全局配置中的环境配置(configuration.getEnvironment()),大家知道这里面存储的就是数据库的连接属性,根据数据源的配置,开启数据库的事务,参数传入了事务等级和是否自动提交,拿到事务后,根据事务和执行器类型获取了一个执行器(Executor),执行器是非常重要的一个环节,下面看一下如何获取执行器:

    1、SqlSession session = sqlSessionFactory.openSession();

    2、org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()

    3、org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource

    4、org.apache.ibatis.session.Configuration#newExecutor(org.apache.ibatis.transaction.Transaction, org.apache.ibatis.session.ExecutorType)

    可以看出前面两行是空值判断,下面是根据三种类型分别创建三种不同的执行器,我们继续看,下面有个根据条件 new CachingExecutor 的地方,我们前面说过一级缓存和二级缓存,这里就是一级缓存的执行器,我们继续往下看,有这样一行代码:

    executor = (Executor)interceptorChain.pluginAll(executor);

    这样看代码作用不太好理解,但是从单词意思上看,调用的是一个拦截器链方法,没错,这个方法就是我们mybatis中所有的插件拦截器执行的地方,我们进入这个方法查看一下逻辑:

    1、SqlSession session = sqlSessionFactory.openSession();

    2、org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()

    3、org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource

    4、org.apache.ibatis.session.Configuration#newExecutor(org.apache.ibatis.transaction.Transaction, org.apache.ibatis.session.ExecutorType)

    5、org.apache.ibatis.plugin.InterceptorChain#pluginAll

    这个方法就非常简单了,这里面是所有拦截器的一个for循环的执行,我们在前面写过一个插件拦截器,即使打印SQL语句输出执行时间,我们再来看一下自定义的拦截器:

    这里面也有一个plugin方法,拦截器链执行的就是这个方法,传入的参数就是我们创建的执行器,我们再来看自定义的拦截器插件类上面的注解,传入的参数也有执行器的类型,

    它会根据执行器的类型判断插件是否要执行,这是拦截器起作用的条件。上面就是获取执行器的过程。我们再来回到第三步,在openSessionFromDataSource方法中,获取事务和执行器对象后,就创建了一个sqlSession对象:

    return new DefaultSqlSession(configuration, executor, autoCommit);

    SqlSession是一个接口,这里默认创建的对象是DefaultSqlSession对象,

    1、SqlSession session = sqlSessionFactory.openSession();

    2、org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()

    3、org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource

    4、org.apache.ibatis.session.defaults.DefaultSqlSession#DefaultSqlSession(org.apache.ibatis.session.Configuration, org.apache.ibatis.executor.Executor, boolean)

    这里只是初始化了几个属性。DefaultSqlSession类实现了SqlSession接口,我们来看下一下SqlSession接口的大致结构:

    这里面定义了很多像selectOne、selectList、update等等的操作数据库的方法,这个接口继承了Closeable接口,可以使用TWR形式操作。我们再来看这个接口的默认实现,DefaultSqlSession类的大致结构:

    这里面对基础的方法有很多默认的实现,这些实现其实就是用类似jdbc的方式访问数据库,调用执行器去执行statement,例如:

    执行时加了很多比如缓存的判断,等等。这些session对象中默认的方法如果直接用来操作数据库并不是很友好,意义也不大。最友好的方式是自己定义mapper。

    通过这个过程我们就拿到了SqlSession对象。我们再来看前面的核心概念,

    现在前面四个对象的创建过程我们都了解了。

    相关文章

      网友评论

        本文标题:MyBatis源码分析(03)SqlSession和Execut

        本文链接:https://www.haomeiwen.com/subject/jmkfdctx.html