我们回顾<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的更多相关文章

  1. MyBatis框架的使用及源码分析(十一) StatementHandler

    我们回忆一下<MyBatis框架的使用及源码分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor> , 这4个Ex ...

  2. MyBatis框架的使用及源码分析(九) Executor

    从<MyBatis框架的使用及源码分析(八) MapperMethod>文中我们知道执行Mapper的每一个接口方法,最后调用的是MapperMethod.execute方法.而当执行Ma ...

  3. MyBatis框架的使用及源码分析(八) MapperMethod

    从 <MyBatis框架中Mapper映射配置的使用及原理解析(七) MapperProxy,MapperProxyFactory> 文中,我们知道Mapper,通过MapperProxy ...

  4. MyBatis框架的使用及源码分析(六) MapperRegistry

    我们先Mapper接口的调用方式,见<MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用>的示例: public void findUserById() { Sql ...

  5. MyBatis框架的使用及源码分析(四) 解析Mapper接口映射xml文件

    在<MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder> 一文中,我们知道mybat ...

  6. MyBatis框架的使用及源码分析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder

    在 <MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用> 的demo中看到了SessionFactory的创建过程: SqlSessionFactory sess ...

  7. MyBatis框架的使用及源码分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor

    Executor分成两大类,一类是CacheExecutor,另一类是普通Executor. 普通类又分为: ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情.它为每个语句的执行 ...

  8. MyBatis框架的使用及源码分析(七) MapperProxy,MapperProxyFactory

    从上文<MyBatis框架中Mapper映射配置的使用及原理解析(六) MapperRegistry> 中我们知道DefaultSqlSession的getMapper方法,最后是通过Ma ...

  9. MyBatis框架的使用及源码分析(三) 配置篇 Configuration

    从上文<MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder> 我们知道XMLConf ...

随机推荐

  1. 《javascript模式--by Stoyan Stefanov》书摘--汇总

    <javascript模式--by Stoyan Stefanov>书摘--基本技巧 http://www.cnblogs.com/liubei/p/JavascriptModeLog1. ...

  2. Python-期末练习

    1.骑车与走路:我们的校园很大很大很大大大大大……,骑个自行车去办事会很快,比如取个快递了,到其他宿舍楼找个同(nv)学(you)了.但实际上,并非去办任何事情都是骑车快,因为骑车总要找车.开锁.停车 ...

  3. 20172333 2017-2018-2 《Java程序设计》第7周学习总结

    20172333 2017-2018-2 <Java程序设计>第7周学习总结 教材学习内容 1.继承是创建新类的快捷方式之一,继承可以使用父类的所有方法及对象. 2.继承具有单向性,父类不 ...

  4. win10 64位系统中安装多个jdk版本的切换问题

    前言: 近期要更换oracle jdk到zulu jdk,因此在本地先安装一版zulu的来进行代码的编译和比较. 注释: 本地电脑之前是oracle jdk 1.8,要更换为zulu jdk 1.8. ...

  5. Jenkins系列-Jenkins忘记密码的修复方法

    找回 admin 用户的密码后,可以登录系统修改其他用户的密码. 1. Jenkins 目录结构 Jenkins 没有使用数据库,所有的信息都保存在 JENKINS_HOME 目录下的文件中.其中 J ...

  6. VS2010中的sln,suo分别是什么含义

    我们通过双击.sln加载出我们的工程. Visual Studio.NET采用两种文件类型(.sln和.suo)来存储特定于解决方案的设置,它们总称为解决方案文件.为解决方案资源管理器提供显示管理文件 ...

  7. do_try_to_free_pages

    /* * This is the main entry point to direct page reclaim. * * If a full scan of the inactive list fa ...

  8. RT-thread 设备驱动组件之IIC总线设备

    本文主要介绍RT-thread中IIC总线设备驱动,涉及到的主要文件有:驱动框架文件(i2c_core.c,i2c_dev.c,i2c-bit-ops.c,i2c_dev.h,i2c.h):底层硬件驱 ...

  9. Springboot2.x+shiro+redis(Lettuce)整合填坑

    主要记录关键和有坑的地方 前提: 1.SpringBoot+shiro已经集成完毕,如果没有集成,先查阅之前的Springboot2.0 集成shiro权限管理 2.redis已经安装完成 3.red ...

  10. Unable to open connection to "Microsoft SQL Server, provider V1.0.5000.0 in framework

    解决办法:1 以管理员身份登陆2 找到ORACLE_HOME文件夹(D:\oracle\ora92),点右键,选属性——安全,在组或用户栏中选"Authenticated Users&quo ...