MyBatis源码阅读(四) --- SqlSession的创建过程
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 主要经历了以下几步:
- 从获取configuration中获取Environment对象,Environment包含了数据库配置;
- 从Environment获取DataSource数据源;
- 从DataSource数据源中获取Connection连接对象;
- 从DataSource数据源中获取TransactionFactory事务工厂,并创建事务Transaction对象;
- 基于事务Transaction创建Executor对象;
- 返回创建好的DefaultSqlSession对象,里面包含configuration和Executor对象;
本篇文章主要总结了Mybatis中SqlSession会话的创建过程,相信大家对SqlSession已经有了比较全面的了解。鉴于笔者水平有限,如果文章有什么错误或者需要补充的,希望小伙伴们指出来,希望这篇文章对大家有帮助。
MyBatis源码阅读(四) --- SqlSession的创建过程相关推荐
- mybatis源码阅读(四):mapper(dao)实例化
转载自 mybatis源码阅读(四):mapper(dao)实例化 在开始分析之前,先来了解一下这个模块中的核心组件之间的关系,如图: 1.MapperRegistry&MapperPro ...
- mybatis源码分析3 - sqlSession的创建
1 引言和主要类 初始化mybatis,也就是创建完单例SqlSessionFactory后,就进入到了mybatis的运行阶段.mybatis每次的运行都是通过SqlSession对象来进行,它是运 ...
- Mybatis 源码探究 (3)创建 SqlSessionFactory对象 执行sqlSession.getMapper()方法
Mybatis 源码探究 (3)创建 SqlSessionFactory对象 时隔许久,终于又能接着来搞他啦.Mybatis 一起来探究吧. 先笑会再进入主题吧 开始啦 一.new SqlSessio ...
- mybatis源码阅读(一):SqlSession和SqlSessionFactory
转载自 mybatis源码阅读(一):SqlSession和SqlSessionFactory 一.接口定义 听名字就知道这里使用了工厂方法模式,SqlSessionFactory负责创建SqlSe ...
- mybatis源码阅读(五) ---执行器Executor
转载自 mybatis源码阅读(五) ---执行器Executor 1. Executor接口设计与类结构图 public interface Executor {ResultHandler NO_ ...
- mybatis源码阅读(二):mybatis初始化上
转载自 mybatis源码阅读(二):mybatis初始化上 1.初始化入口 //Mybatis 通过SqlSessionFactory获取SqlSession, 然后才能通过SqlSession与 ...
- Mybatis源码阅读(一):Mybatis初始化1.1 解析properties、settings
*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如 ...
- mybatis源码阅读(八) ---Interceptor了解一下
转载自 mybatis源码阅读(八) ---Interceptor了解一下 1 Intercetor MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用.默认情况下,MyBatis允许 ...
- mybatis源码阅读(七) ---ResultSetHandler了解一下
转载自 mybatis源码阅读(七) ---ResultSetHandler了解一下 1.MetaObject MetaObject用于反射创建对象.反射从对象中获取属性值.反射给对象设置属性值,参 ...
- mybatis源码阅读(六) ---StatementHandler了解一下
转载自 mybatis源码阅读(六) ---StatementHandler了解一下 StatementHandler类结构图与接口设计 BaseStatementHandler:一个抽象类,只是实 ...
最新文章
- python bytearray拼接_python数据类型 ——bytes 和 bytearray
- STM32F10x_StdPeriph_Lib_V3.5.0库时钟分析及如何配置
- 编程之美2.7 最大公约数,最小公倍数
- Hadoop RPC protocol description--转
- Python并发编程—进程
- Linux常用命令之wget
- mysql四种事务级别_【MySQL 知识】四种事务隔离级别
- 2016中国信息通信大数据大会召开在即,精彩看点提前揭晓
- 如何在其他程序的窗口上创建按钮并使之能响应
- 无意中发现的一份清华大佬的刷题笔记!
- java 调用casperjs_Java程序去调用并执行shell脚本及问题总结(推荐)
- Linux用户空间将虚拟地址转化为物理地址
- 使用OWC 做图表时按周、月、年设置时间刻度是参数无效问题解决方法
- 在 Android* 平台上设置原生 OpenGL ES*
- 【深度学习】基于Keras的手写体识别
- c语言转化音乐格式转换器安卓版,音频提取格式转换APP
- IBM X3850 X5连接存储后…
- windows7 照片查看器无法打开图片, windows提示因为可用内存不足,但我的内存4G?
- SAP系统销售流程成本和收入的确认
- git 基础命令大全
热门文章
- hbase 查询某列_hbase shell使用STARTROW、ENDROW、FILTER查出指定的列
- iis6扩展php_教你IIS6的PHP最佳配置方法
- 数组存放字符_字符串的 3种表示方法,不会用不是合格的程序员
- 2021-08-3126. 删除有序数组中的重复项 数组
- 实操:SparrowRecsys的首次运行
- 114.二叉树展开为链表
- Adam自适应矩估计
- php5.6软件下载,【PHP下载】PHP for Linux 5.6.6-ZOL软件下载
- Can Place Flowers
- KNN(k-nearest neighbor algorithm)--从原理到实现