创建好了sqlSessionFactory,但是我们最终要使用的是创建好的代理对象。而代理对象的创建需要sqlSession来参与。所以我们还得看看sqlSession是什么东西,他的作用是什么。
1、SqlSession的创建
这里我还是跟一下源代码吧 这一块代码不是特别多
//创建sqlSession
SqlSession sqlSession = factory.openSession();
DefaultSqlSessionFactory 66 line
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
DefaultSqlSession var8;
try {
//获取配置环境
Environment environment = this.configuration.getEnvironment();
//获取事务工厂(从环境中拿,如果没有,new一个)
TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
//2、创建一个tx
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//3、创建一个执行器
Executor executor = this.configuration.newExecutor(tx, execType);
//4、创建sqlSession
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;
}
2、Transaction的创建
public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
this.dataSource = ds;
this.level = desiredLevel;
this.autoCommit = desiredAutoCommit;
}
3、执行器的创建
这一块会牵扯到批量执行器与 简单的执行器 默认是简单的,要配置需要在Configuration配置
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? this.defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Object 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);
}
//如果开启了缓存,则会包装下前面创建的执行器
if (this.cacheEnabled) {
executor = new CachingExecutor((Executor)executor);
}
//插件再去包装下执行器
Executor executor = (Executor)this.interceptorChain.pluginAll(executor);
return executor;
}
看一下缓存下的执行器包装
也就是new一个对象,持有以前的执行器的引用罢了 将以前执行器的wrapper执行了创建的这个对象
public CachingExecutor(Executor delegate) {
this.delegate = delegate;
delegate.setExecutorWrapper(this);
}
看看插件时怎么包装的
这一块会涉及到Interceptor这个接口,我们需要实现这个接口的方法,然后自己去包装执行器,返回包装之后的结果就好了
//实现这个接口,去重写plugin方法就好了。
public interface Interceptor {
Object intercept(Invocation var1) throws Throwable;
default Object plugin(Object target) {
return Plugin.wrap(target, this);
}
default void setProperties(Properties properties) {
}
}
4、sqlSession的实例化
使用上面创建好的执行器与Transaction去构造sqlSession
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
this.configuration = configuration;
this.executor = executor;
this.dirty = false;
this.autoCommit = autoCommit;
}
可以看到sqlSession持有执行器、配置信息的引用。下一篇分析sqlSession的使用–涉及到接口的代理对象的创建–sql的提交–数据的查询等等
这里看下sqlSession的继承关系
使用完之后别忘了session.close()