上一篇中主要介绍了Mybatis解析配置文件的整体流程,并创建了SqlSessionFactory对象,SqlSessionFactory顾名思义就是创建SqlSession的工厂,那么接着往下来,看看sqlSessionFactory.openSession()中都干了些什么。
openSession()方法
开启数据库会话,创建数据库连接的会话对象(事务对象、事务工厂、执行器、如果有插件会进行插件解析)
@Test
public void test02 () {
// 根据全局配置文件创建出SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
// SqlSessionFactory:负责创建SqlSession对象的工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// SqlSession:表示跟数据库建议的一次会话
// 获取数据库的会话,创建出数据库连接的会话对象(事务工厂,事务对象,执行器,如果有插件的话会进行插件的解析)
SqlSession sqlSession = sqlSessionFactory.openSession();
Emp empByEmpno = null;
try {
// 获取要调用的接口类,创建出对应的mapper的动态代理对象(mapperRegistry.knownMapper)
EmpDao mapper = sqlSession.getMapper(EmpDao.class);
// 调用方法开始执行
empByEmpno = mapper.findEmpByEmpnoAndEname(7369, "SMITH");
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
System.out.println(empByEmpno);
}
openSession具体执行流程
//execType 执行器类型,默认会给定一个SIMPLE Executor
//level 隔离级别,共NONE、READ_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ、SERIALIZABLE五种类型
//autoCommit 事务自动提交 默认false
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
//
Transaction tx = null;
try {
//获取mybatis-config.xml文件中Environment标签对象
final Environment environment = configuration.getEnvironment();
//创建事务工厂
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//创建Transaction对象
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//创建Executor
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();
}
}
getTransactionFactoryFromEnvironment
如果没有配置事务工厂,则使用默认的ManagedTransactionFactory,否则根据配置进行创建
//构建事务工厂
private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
//如果没有配置事务工厂,则返回托管事务工厂
if (environment == null || environment.getTransactionFactory() == null) {
return new ManagedTransactionFactory();
}
return environment.getTransactionFactory();
}
newExecutor
创建Executor,默认会使用SIMPLE.EXECUTOR
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
//下面两行代码一样,莫得什么不同
//如果executorType为null,则创建一个SIMPLE的Executor
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
//根据参数,创建不同的Executor
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
//根据配置,看是否开启二级缓存
//如果开启了缓存,则封装成CachingExecutor
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
//通过插件,可以修改Executor
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
Executor
创建Executor时会调用父类BaseExecutor的构造器,类中有对缓存的设置。
public abstract class BaseExecutor implements Executor {
private static final Log log = LogFactory.getLog(BaseExecutor.class);
protected Transaction transaction;
protected Executor wrapper;
//延迟队列,线程安全
protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;
// 一级缓存,用于缓存该Executor对象查询结果集映射得到的结果对象
protected PerpetualCache localCache;
// 一级缓存,用于缓存输出类型的参数
protected PerpetualCache localOutputParameterCache;
protected Configuration configuration;
// 用来记录嵌套查询的层数
protected int queryStack;
private boolean closed;
protected BaseExecutor(Configuration configuration, Transaction transaction) {
this.transaction = transaction;
this.deferredLoads = new ConcurrentLinkedQueue<>();
this.localCache = new PerpetualCache("LocalCache");
this.localOutputParameterCache = new PerpetualCache("LocalOutputParameterCache");
this.closed = false;
this.configuration = configuration;
this.wrapper = this;
}
}
CachingExecutor
如果开启了二级缓存,则会对Executor进行一次封装。
public CachingExecutor(Executor delegate) {
this.delegate = delegate;
delegate.setExecutorWrapper(this);
}
总结:
openSession中,只是获取了数据库会话,并创建了事务会话、工厂、执行器。并没有进行数据库的连接。