上一篇MyBatis源码解析系列中,我们说完了SqlSessionFactory的诞生过程。这一篇中,我们要根据SqlSessionFactory工厂去得到SqlSession。那么,在这个过程中,究竟做了些什么?我们一一去解读。
一、SqlSession怎么来的
SqlSession是一个接口类,继承了Closeable(只有一个从AutoCloseable接口类继承来的方法close)。在SqlSession接口类中,提供了各种查询、删除、更新、提交、回滚等等方法。我们看类图:
既然是个接口类,那么总要有实现类去做这些事情,才能显示出接口类的价值。那么SqlSession是怎么来的?实现类是谁?
在篇二中,我们得到了SqlSessionFactory,它的默认实现类是DefaultSqlSessionFactory,既然是工厂实现类,那么DefaultSqlSessionFactory这里就是生产SqlSession的工厂车间。从这里,我们就可以找到SqlSession的来源。我们去看看。
从类图中我们可以看到,DefaultSqlSessionFactory提供了很多openSession方法,返回的对象类型就是SqlSession。
我们看下源码,源码中分为两种方式生产SqlSession,一种是使用方法private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit),一种是使用重载的private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection)。
public SqlSession openSession() { return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false); } public SqlSession openSession(boolean autoCommit) { return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, autoCommit); } public SqlSession openSession(ExecutorType execType) { return this.openSessionFromDataSource(execType, (TransactionIsolationLevel)null, false); } public SqlSession openSession(TransactionIsolationLevel level) { return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), level, false); } public SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level) { return this.openSessionFromDataSource(execType, level, false); } public SqlSession openSession(ExecutorType execType, boolean autoCommit) { return this.openSessionFromDataSource(execType, (TransactionIsolationLevel)null, autoCommit); } public SqlSession openSession(Connection connection) { return this.openSessionFromConnection(this.configuration.getDefaultExecutorType(), connection); } public SqlSession openSession(ExecutorType execType, Connection connection) { return this.openSessionFromConnection(execType, connection); }
那我们就分开来看下这两方法。
1、private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit):
源码如下:
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; DefaultSqlSession var8; try { Environment environment = this.configuration.getEnvironment(); TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment); tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); Executor executor = this.configuration.newExecutor(tx, execType); var8 = new DefaultSqlSession(this.configuration, executor, autoCommit); } catch (Exception var12) { this.closeTransaction(tx); throw ExceptionFactory.wrapException("Error opening session. Cause: " + var12, var12); } finally { ErrorContext.instance().reset(); } return var8; }
我们一行行来解释。结合我们的debug过程。
①在Environment environment = this.configuration.getEnvironment();中,根据我们在得到SqlSessionFactory过程中设置的对象configuration来获取在解析