Mybatis源码阅读系列文章:

MyBatis源码阅读(一) --- 源码阅读环境搭建

MyBatis源码阅读(二) --- 执行流程分析

MyBatis源码阅读(三) --- 配置信息的解析以及SqlSessionFactory构建过程

MyBatis源码阅读(四) --- SqlSession的创建过程

MyBatis源码阅读(五) ---Mapper接口的获取过程

MyBatis源码阅读(六) ---mapper方法具体执行流程分析

MyBatis源码阅读(七) --- 查询结果集封装流程

MyBatis源码阅读(八) --- Executor执行器

MyBatis源码阅读(九) --- 插件原理

MyBatis源码阅读(十) --- 一级缓存、二级缓存工作原理

MyBatis源码阅读(十一) --- MyBatis事务管理机制

MyBatis源码阅读(十二) --- Spring加载MyBatis过程

目录

一、概述

二、SqlSession的创建过程

三、 SqlSession的创建过程流程图

四、总结


一、概述

前面一篇文章我们详细分析了SqlSessionFactory的创建过程,既然SqlSessionFactory有了,那么我们就可以通过sqlSessionFactory.openSession()来开启一个会话了,进而实现对数据库的操作,那么sqlSessionFactory.openSession()到底干了哪些事情呢?本篇文章就来详细了解一下。

SqlSession是Mybatis的高级接口,类似于JDBC操作的connection对象,它包装了数据库连接,通过这个接口我们可以实现增删改查,提交/回滚事务,关闭连接,获取代理类等操作。SqlSession是线程不安全的,每个线程都会有自己唯一的SqlSession,不同线程间调用同一个SqlSession会出现问题,因此在使用完后需要及时关闭。

SqlSession是个接口,其默认实现是DefaultSqlSession,另外一个子类是SqlSessionManager。

以下是SqlSession常见的方法:

public interface SqlSession extends Closeable {/*** 查询一个结果对象**/ <T> T selectOne(String statement, Object parameter);/*** 查询一个结果集合**/ <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);/*** 查询一个map**/ <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);/*** 查询游标**/ <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);/*** 插入**/ int insert(String statement, Object parameter);/*** 修改**/ int update(String statement, Object parameter);/*** 删除**/int delete(String statement, Object parameter);/*** 提交事物**/void commit(boolean force);/*** 回滚事物**/void rollback(boolean force);List<BatchResult> flushStatements();void close();void clearCache();Configuration getConfiguration();/*** 获取映射代理类**/<T> T getMapper(Class<T> type);/*** 获取数据库连接**/Connection getConnection();
}

可以看到,SqlSession可以实现增删改查,提交/回滚事务,关闭连接,获取代理类等操作,下面就来看下SqlSession详细的创建过程。

二、SqlSession的创建过程

SqlSession sqlSession = sqlSessionFactory.openSession()

通过sqlSessionFactory的openSession()开启一个会话。

DefaultSqlSessionFactory中有两种创建会话的方式:

  • openSessionFromDataSource:从数据源中获取SqlSession对象,SqlSession实际是对数据库连接的一层包装,数据库连接是个珍贵的资源,如果频繁的创建销毁将会影响吞吐量,这种方式就是从数据库连接池中获取一个连接,然后包装成一个SqlSession。
  • openSessionFromConnection:由已有连接获取SqlSession对象。
//默认使用的是DefaultSqlSessionFactory
//org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()
@Override
public SqlSession openSession() {//configuration中有默认执行器类型,是SIMPLE简单类型执行器(SimpleExecutor)//从数据库连接池中获取一个连接,然后包装成一个SqlSession对像//可以复用数据库连接return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}

这里我们以openSessionFromDataSource为例:从数据源连接池获取一个SqlSession会话

//org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {//事务对象Transaction tx = null;try {//从configuration对象中获取到我们之前解析的environment环境信息final Environment environment = configuration.getEnvironment();//事务工厂,这里是JbdcTransactionFactory工厂类final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);//通过事务工厂创建JbdcTransaction事务,传入数据源等信息tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);//创建Executor执行器final Executor executor = configuration.newExecutor(tx, execType);//创建DefaultSqlSession会话,传入Configuration、Executor对象return new DefaultSqlSession(configuration, executor, autoCommit);} catch (Exception e) {closeTransaction(tx); // may have fetched a connection so lets call close()throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);} finally {ErrorContext.instance().reset();}
}

我们看到,创建SqlSession主要需要下面几个东西:

  • 【a】environment

环境对象,这是在mybatis-config.xml中配置的,主要用来生成TransactionFactory,而TransactionFactory是用来生成Transaction事务的。

  • 【b】Transaction

事务对象,我们都知道sql执行时涉及到事务,需要提交或回滚什么的。创建Transaction事务对象,需要传入我们在mybatis-config.xml中配置的数据源信息(从environment获取,因为之前解析XML的时候保存进去了),通过这些参数,transactionFactory就可以生成Transaction。

  • 【c】executor

执行器,它是一个接口,是Mybatis的核心执行器,相当于jdbc中的statement,发送sql语句并执行。executor的继承图如下所示,默认使用的是SimpleExecutor简单类型的执行器。

  • 【d】configuration

全局配置信息

我们Debug一下,查看具体创建过程各个属性的值:

至此,我们的SqlSession对象就创建成功了,其中还涉及到Executor执行器的创建过程,暂且先跳过,后面专门使用一篇文章分析Executor的原理。

三、 SqlSession的创建过程流程图

四、总结

openSessionFromDataSource 主要经历了以下几步:

  1. 从获取configuration中获取Environment对象,Environment包含了数据库配置;
  2. 从Environment获取DataSource数据源;
  3. 从DataSource数据源中获取Connection连接对象;
  4. 从DataSource数据源中获取TransactionFactory事务工厂,并创建事务Transaction对象;
  5. 基于事务Transaction创建Executor对象;
  6. 返回创建好的DefaultSqlSession对象,里面包含configuration和Executor对象;

本篇文章主要总结了Mybatis中SqlSession会话的创建过程,相信大家对SqlSession已经有了比较全面的了解。鉴于笔者水平有限,如果文章有什么错误或者需要补充的,希望小伙伴们指出来,希望这篇文章对大家有帮助。

MyBatis源码阅读(四) --- SqlSession的创建过程相关推荐

  1. mybatis源码阅读(四):mapper(dao)实例化

    转载自   mybatis源码阅读(四):mapper(dao)实例化 在开始分析之前,先来了解一下这个模块中的核心组件之间的关系,如图: 1.MapperRegistry&MapperPro ...

  2. mybatis源码分析3 - sqlSession的创建

    1 引言和主要类 初始化mybatis,也就是创建完单例SqlSessionFactory后,就进入到了mybatis的运行阶段.mybatis每次的运行都是通过SqlSession对象来进行,它是运 ...

  3. Mybatis 源码探究 (3)创建 SqlSessionFactory对象 执行sqlSession.getMapper()方法

    Mybatis 源码探究 (3)创建 SqlSessionFactory对象 时隔许久,终于又能接着来搞他啦.Mybatis 一起来探究吧. 先笑会再进入主题吧 开始啦 一.new SqlSessio ...

  4. mybatis源码阅读(一):SqlSession和SqlSessionFactory

    转载自  mybatis源码阅读(一):SqlSession和SqlSessionFactory 一.接口定义 听名字就知道这里使用了工厂方法模式,SqlSessionFactory负责创建SqlSe ...

  5. mybatis源码阅读(五) ---执行器Executor

    转载自  mybatis源码阅读(五) ---执行器Executor 1. Executor接口设计与类结构图 public interface Executor {ResultHandler NO_ ...

  6. mybatis源码阅读(二):mybatis初始化上

    转载自  mybatis源码阅读(二):mybatis初始化上 1.初始化入口 //Mybatis 通过SqlSessionFactory获取SqlSession, 然后才能通过SqlSession与 ...

  7. Mybatis源码阅读(一):Mybatis初始化1.1 解析properties、settings

    *************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如 ...

  8. mybatis源码阅读(八) ---Interceptor了解一下

    转载自  mybatis源码阅读(八) ---Interceptor了解一下 1 Intercetor MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用.默认情况下,MyBatis允许 ...

  9. mybatis源码阅读(七) ---ResultSetHandler了解一下

    转载自  mybatis源码阅读(七) ---ResultSetHandler了解一下 1.MetaObject MetaObject用于反射创建对象.反射从对象中获取属性值.反射给对象设置属性值,参 ...

  10. mybatis源码阅读(六) ---StatementHandler了解一下

    转载自  mybatis源码阅读(六) ---StatementHandler了解一下 StatementHandler类结构图与接口设计 BaseStatementHandler:一个抽象类,只是实 ...

最新文章

  1. python bytearray拼接_python数据类型 ——bytes 和 bytearray
  2. STM32F10x_StdPeriph_Lib_V3.5.0库时钟分析及如何配置
  3. 编程之美2.7 最大公约数,最小公倍数
  4. Hadoop RPC protocol description--转
  5. Python并发编程—进程
  6. Linux常用命令之wget
  7. mysql四种事务级别_【MySQL 知识】四种事务隔离级别
  8. 2016中国信息通信大数据大会召开在即,精彩看点提前揭晓
  9. 如何在其他程序的窗口上创建按钮并使之能响应
  10. 无意中发现的一份清华大佬的刷题笔记!
  11. java 调用casperjs_Java程序去调用并执行shell脚本及问题总结(推荐)
  12. Linux用户空间将虚拟地址转化为物理地址
  13. 使用OWC 做图表时按周、月、年设置时间刻度是参数无效问题解决方法
  14. 在 Android* 平台上设置原生 OpenGL ES*
  15. 【深度学习】基于Keras的手写体识别
  16. c语言转化音乐格式转换器安卓版,音频提取格式转换APP
  17. IBM X3850 X5连接存储后…
  18. windows7 照片查看器无法打开图片, windows提示因为可用内存不足,但我的内存4G?
  19. SAP系统销售流程成本和收入的确认
  20. git 基础命令大全

热门文章

  1. hbase 查询某列_hbase shell使用STARTROW、ENDROW、FILTER查出指定的列
  2. iis6扩展php_教你IIS6的PHP最佳配置方法
  3. 数组存放字符_字符串的 3种表示方法,不会用不是合格的程序员
  4. 2021-08-3126. 删除有序数组中的重复项 数组
  5. 实操:SparrowRecsys的首次运行
  6. 114.二叉树展开为链表
  7. Adam自适应矩估计
  8. php5.6软件下载,【PHP下载】PHP for Linux 5.6.6-ZOL软件下载
  9. Can Place Flowers
  10. KNN(k-nearest neighbor algorithm)--从原理到实现