MyBatis框架的使用及源码分析(五) DefaultSqlSessionFactory和DefaultSqlSession
我们回顾<MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用> 一文的示例
private static SqlSessionFactory getSessionFactory() {
SqlSessionFactory sessionFactory = null;
String resource = "mybatisConfig.xml";
try {
sessionFactory = new SqlSessionFactoryBuilder().build(Resources
.getResourceAsReader(resource));
} catch (IOException e) {
e.printStackTrace();
}
return sessionFactory;
}
@Test
public void findUserById() {
SqlSessionFactory sqlSessionFactory = getSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectByPrimaryKey(1l);
System.out.println(user.getId() + " / " + user.getName());
}
SqlSessionFactoryBuilder 创建出SqlSessionFactory,然后从SqlSessionFactory中得到SqlSession,最后通过SqlSession得到Mapper接口对象进行数据库操作。
我们跟踪SqlSessionFactoryBuilder的源代码:
package org.apache.ibatis.session;
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
我们可以看到这个类用很多的构造方法,但主要分为三大类:
1、通过读取字符流(Reader)的方式构件SqlSessionFactory。
2、通过字节流(InputStream)的方式构件SqlSessionFacotry。
3、通过Configuration对象构建SqlSessionFactory。
第1、2种方式是通过配置文件方式,第3种是通过Java代码方式。
build方法返回SqlSessionFactory接口的实现对象DefaultSqlSessionFactory。
我们继续跟踪DefaultSqlSessionFactory的openSession()方法:
package org.apache.ibatis.session.defaults; /**
* @author Clinton Begin
*/
public class DefaultSqlSessionFactory implements SqlSessionFactory { private final Configuration configuration; public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
} public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
} public SqlSession openSession(boolean autoCommit) {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
} public SqlSession openSession(ExecutorType execType) {
return openSessionFromDataSource(execType, null, false);
} public SqlSession openSession(TransactionIsolationLevel level) {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), level, false);
} public SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level) {
return openSessionFromDataSource(execType, level, false);
} public SqlSession openSession(ExecutorType execType, boolean autoCommit) {
return openSessionFromDataSource(execType, null, autoCommit);
} public SqlSession openSession(Connection connection) {
return openSessionFromConnection(configuration.getDefaultExecutorType(), connection);
} public SqlSession openSession(ExecutorType execType, Connection connection) {
return openSessionFromConnection(execType, connection);
} public Configuration getConfiguration() {
return configuration;
} private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
final Executor executor = configuration.newExecutor(tx, execType);
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();
}
} private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
try {
boolean autoCommit;
try {
autoCommit = connection.getAutoCommit();
} catch (SQLException e) {
// Failover to true, as most poor drivers
// or databases won't support transactions
autoCommit = true;
}
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
final Transaction tx = transactionFactory.newTransaction(connection);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
} private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
if (environment == null || environment.getTransactionFactory() == null) {
return new ManagedTransactionFactory();
}
return environment.getTransactionFactory();
} private void closeTransaction(Transaction tx) {
if (tx != null) {
try {
tx.close();
} catch (SQLException ignore) {
// Intentionally ignore. Prefer previous error.
}
}
} }
这么多的openSession重载方法,都是通过传入不同的参数构造SqlSession实例,有通过设置事务是否自动提交"autoCommit",有设置执行器类型"ExecutorType"来构造的,还有事务的隔离级别等等。
最后一个方法就告诉我们可以通过SqlSessionFactory来获取Configuration对象。
mybatis创建sqlsession经过了以下几个主要步骤:
1. 从核心配置文件mybatis-config.xml中获取Environment(这里面是数据源);
2. 从Environment中取得DataSource;
3. 从Environment中取得TransactionFactory;
4. 从DataSource里获取数据库连接对象Connection;
5. 在取得的数据库连接上创建事务对象Transaction;
6. 创建Executor对象(该对象非常重要,事实上sqlsession的所有操作都是通过它完成的);
7. 创建sqlsession对象。
从源码中可以知道DefaultSqlSession是SqlSession的实例。
new DefaultSqlSession(configuration, executor, autoCommit);
那么通过此文,我们就清楚的知道了SqlSessionFactory和SqlSession具体的创建过程,知道了他们的实现类是DefaultSqlSessionFactory和DefaultSqlSession。
MyBatis框架的使用及源码分析(五) DefaultSqlSessionFactory和DefaultSqlSession的更多相关文章
- MyBatis框架的使用及源码分析(十一) StatementHandler
我们回忆一下<MyBatis框架的使用及源码分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor> , 这4个Ex ...
- MyBatis框架的使用及源码分析(九) Executor
从<MyBatis框架的使用及源码分析(八) MapperMethod>文中我们知道执行Mapper的每一个接口方法,最后调用的是MapperMethod.execute方法.而当执行Ma ...
- MyBatis框架的使用及源码分析(八) MapperMethod
从 <MyBatis框架中Mapper映射配置的使用及原理解析(七) MapperProxy,MapperProxyFactory> 文中,我们知道Mapper,通过MapperProxy ...
- MyBatis框架的使用及源码分析(六) MapperRegistry
我们先Mapper接口的调用方式,见<MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用>的示例: public void findUserById() { Sql ...
- MyBatis框架的使用及源码分析(四) 解析Mapper接口映射xml文件
在<MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder> 一文中,我们知道mybat ...
- MyBatis框架的使用及源码分析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder
在 <MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用> 的demo中看到了SessionFactory的创建过程: SqlSessionFactory sess ...
- MyBatis框架的使用及源码分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor
Executor分成两大类,一类是CacheExecutor,另一类是普通Executor. 普通类又分为: ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情.它为每个语句的执行 ...
- MyBatis框架的使用及源码分析(七) MapperProxy,MapperProxyFactory
从上文<MyBatis框架中Mapper映射配置的使用及原理解析(六) MapperRegistry> 中我们知道DefaultSqlSession的getMapper方法,最后是通过Ma ...
- MyBatis框架的使用及源码分析(三) 配置篇 Configuration
从上文<MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder> 我们知道XMLConf ...
随机推荐
- canvas学习(三):文字渲染
一.绘制基本的文字: var canvas = document.getElementById("myCanvas") var ctx = canvas.getContext('2 ...
- Python—元组(戴上了枷锁的列表)
一.概念 元组属于不可变序列,元组是包含多个元素的类型,元素之间用逗号分割.例如:t1=123,456,“hello”元组可以是空的,t2=()元组包含一个元素时:t3=123,元组外侧可以使用括号, ...
- 视频播放截图及简要文字介绍——Thunder团队
视频播放截图及简要文字介绍 图一:团队Logo ——从此我们有了自己的标志 图二:扫描本地书籍 ——可阅读本地的喜爱书籍 图三:在本地添加自己喜爱的图书 ——将自己喜爱的书籍加入书架,方便阅读 图四: ...
- 2019寒假训练营寒假作业(三) MOOC的网络空间安全概论笔记部分
目录 第五章 网络攻防技术 5.1:网络信息收集技术--网络踩点 信息收集的必要性及内容 网络信息收集技术 网络踩点(Footprinting) 网络踩点常用手段 5.2:网络信息收集技术 --网络扫 ...
- java连接数据库的两种方法总结
方法一:使用jdbc-odbc桥连接sql server,作为中间媒介连接数据库 1.配置数据源:打开控制面版->管理工具->数据源(ODBC)->选用户DSN,按下添加按钮-> ...
- DAY5敏捷冲刺
站立式会议 工作安排 (1)服务器配置 对单词学习的记录储存 (2)数据库配置 单词学习记录+用户信息 燃尽图 燃尽图有误,已重新修改,先贴卡片的界面,后面补修改后燃尽图 代码提交记录
- finecms
finecms地址 还不错的国内CMS http://www.dayrui.com/doc/246.html
- hadoop下安装mysql
http://www.cnblogs.com/zhuyp1015/p/3561470.html 第一步:先把这个文件放入到linux环境下桌面. 接着编写脚本:sudo apt-get u ...
- 文件“bin\Debug\WindowsFormsApplication2.exe”正由另一进程使用,因此该进程无法访问该文件。
http://zhidao.baidu.com/question/221394579.html?qbl=relate_question_2&word=%BE%AF%B8%E6%094%09%C ...
- 【Python】Python中的引用和赋值
本文转自:http://my.oschina.net/leejun2005/blog/145911 在 python 中赋值语句总是建立对象的引用值,而不是复制对象.因此,python 变量更像是指针 ...