关于mybatis里面的Executor--转载

原文地址:http://blog.csdn.net/w_intercool/article/details/7893344

使用mybatis查寻数据,跟踪其执行流程

最开始执行的语句

  1. this.getSqlSession().selectList("QUERY-QUESTION", data, rowBounds);  

这里需要找到sqlsession是从哪里来的

getSqlSession是SqlSessionDaoSupport类里面的方法,该类通过spring的自动注入可以把sqlSessionTemplate注入进来,当然这里的sqlSessionTemplate是需要spring配置的

  1. @Autowired(required = false)  
  2. public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {  
  3.   this.sqlSession = sqlSessionTemplate;  
  4.   this.externalSqlSession = true;  
  5. }  
  1. <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">  
  2.         <constructor-arg index="0" ref="sqlSessionFactory"/>  
  3.         <constructor-arg index="1" value="BATCH"/>  
  4.     </bean>  

@Autowired(required = false)是通过类型匹配来注入的,如果没有找到相应对,就不用注入

所以selectList方法为SqlSessionTemlate里面的,再看SqlSessionTemplage,里面的都是通过sqlSessionProxy来执行selectList方法的,也就是通过代理方式来的

  1. public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,  
  2.     PersistenceExceptionTranslator exceptionTranslator) {  
  3.   
  4.   notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");  
  5.   notNull(executorType, "Property 'executorType' is required");  
  6.   
  7.   this.sqlSessionFactory = sqlSessionFactory;  
  8.   this.executorType = executorType;  
  9.   this.exceptionTranslator = exceptionTranslator;  
  10.   this.sqlSessionProxy = (SqlSession) newProxyInstance(  
  11.       SqlSessionFactory.class.getClassLoader(),  
  12.       new Class[] { SqlSession.class },  
  13.       new SqlSessionInterceptor());  
  14. }  


这里用到了java的动态代理,详细可以见java api,有详细的说明

SqlSessionInterceptor实现了InvocationHandler,在invoke方法里面的开始有这样代码,那里是真正的sqlsession

  1. final SqlSession sqlSession = getSqlSession(  
  2.          SqlSessionTemplate.this.sqlSessionFactory,  
  3.          SqlSessionTemplate.this.executorType,  
  4.          SqlSessionTemplate.this.exceptionTranslator);  

跟踪geteSqlSession可以找到他的创建来源,见

  1. SqlSession session = sessionFactory.openSession(executorType);  


继续跟踪可以找到DefaultSqlSessionFactory里面的该方法

  1. private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {  
  2.   Transaction tx = null;  
  3.   try {  
  4.     final Environment environment = configuration.getEnvironment();  
  5.     final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);  
  6.     tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);  
  7.     final Executor executor = configuration.newExecutor(tx, execType, autoCommit);  
  8.     return new DefaultSqlSession(configuration, executor);  
  9.   } catch (Exception e) {  
  10.     closeTransaction(tx); // may have fetched a connection so lets call close()  
  11.     throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);  
  12.   } finally {  
  13.     ErrorContext.instance().reset();  
  14.   }  
  15. }  


通过

  1. final Executor executor = configuration.newExecutor(tx, execType, autoCommit);  

你就知道executor是怎么回来的了

mybatis默认使用了cache,在创建exector时,外面就包了一层CacheExecutor,详细见

  1. public Executor newExecutor(Transaction transaction, ExecutorType executorType, boolean autoCommit) {  
  2.   executorType = executorType == null ? defaultExecutorType : executorType;  
  3.   executorType = executorType == null ? ExecutorType.SIMPLE : executorType;  
  4.   Executor executor;  
  5.   if (ExecutorType.BATCH == executorType) {  
  6.     executor = new BatchExecutor(this, transaction);  
  7.   } else if (ExecutorType.REUSE == executorType) {  
  8.     executor = new ReuseExecutor(this, transaction);  
  9.   } else {  
  10.     executor = new SimpleExecutor(this, transaction);  
  11.   }  
  12.   if (cacheEnabled) {  
  13.     executor = new CachingExecutor(executor, autoCommit);  
  14.   }  
  15.   executor = (Executor) interceptorChain.pluginAll(executor);  
  16.   return executor;  
  17. }  


CachingExecutor可以使mybatis先从缓存中提取数据,数据缓存中没有数据时才从数据库里面提取数据。

原文地址:https://www.cnblogs.com/davidwang456/p/4693090.html