SqlSession
通过SqlSession sqlSession = sqlSessionFactory.openSession();获取SqlSession实例,
DefaultSqlSessionFactory
public SqlSession openSession() {return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);}//从数据源获取数据库连接private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {Transaction tx = null;try {//获取mybatis配置文件中的environment对象final Environment environment = configuration.getEnvironment();//从environment获取transactionFactory对象final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);//创建事务对象tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);//根据配置创建executorfinal Executor executor = configuration.newExecutor(tx, execType);//创建DefaultSqlSessionreturn 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();}}
openSessionFromDataSource主要分为一下几个步骤:
1、获取mybatis配置文件中的environment对象
final Environment environment = configuration.getEnvironment();
2、从environment获取transactionFactory对象
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
3、创建事务对象
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
这里以JdbcTransactionFactory(TransactionFactory实现类)为例,获取JdbcTransaction(Transaction实现类)
JdbcTransactionFactory
public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {return new JdbcTransaction(ds, level, autoCommit);}
4、创建Executor对象
Configuration
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {executorType = executorType == null ? defaultExecutorType : executorType;executorType = executorType == null ? ExecutorType.SIMPLE : executorType;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);}//如果有<cache>节点,通过装饰器,添加二级缓存的能力if (cacheEnabled) {executor = new CachingExecutor(executor);}//通过interceptorChain遍历所有的插件为executor增强,添加插件的功能executor = (Executor) interceptorChain.pluginAll(executor);return executor;}
1)调用Configuration对象方法newExecutor进行创建,根据executorType选择相应的Executor实现类,这里以选择默认的SIMPLE为例,则选择新建SimpleExecutor对象。
2)判断全局的cacheEnabled值(默认为true),通过装饰器,添加二级缓存的能力。因此,二级缓存配置需要在mybatis-config.xml的cache进行开启。另外从这里,可以看到若是cacheEnabled为false,则executor并未增加二级缓存的能力,表明二级缓存不能使用。
3)通过InterceptorChain的pluginAll方法遍历所有的插件为executor增强,添加插件的功能
InterceptorChain
public Object pluginAll(Object target) {for (Interceptor interceptor : interceptors) {target = interceptor.plugin(target);}return target;}
ThresholdInterceptor一个Interceptor接口的自定义实现类
ThresholdInterceptor
@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}
Plugin类wrap方法,实现InvocationHandler,Interceptor的代理类。在wrap方法中,可以看到,会根据@Intercepts的信息以及目标对象的信息,判断是否需要对该对象进行拦截代理。
Plugin
//静态方法,用于帮助Interceptor生成动态代理public static Object wrap(Object target, Interceptor interceptor) {//解析Interceptor上@Intercepts注解得到的signature信息Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);Class<?> type = target.getClass();//获取目标对象的类型Class<?>[] interfaces = getAllInterfaces(type, signatureMap);//获取目标对象实现的接口(拦截器可以拦截4大对象实现的接口)if (interfaces.length > 0) {//使用jdk的方式创建动态代理return Proxy.newProxyInstance(type.getClassLoader(),interfaces,new Plugin(target, interceptor, signatureMap));}return target;}
注意:Configuration对象中保存有默认的executorType:ExecutorType defaultExecutorType = ExecutorType.SIMPLE;BatchExecutor、ReuseExecutor、SimpleExecutor都继承于BaseExecutor抽象类,BaseExecutor主要用于为一些基础属性如configuration、transaction等赋初始值。
5、创建DefaultSqlSession,获取sqlSession完成。