MyBatis源码的学习(4)---MapperProxy的invoke方法

MyBatis源码的学习(4)---MapperProxy的invoke方法_第1张图片

 public Object execute(SqlSession sqlSession, Object[] args) {
    Object result;
    switch (command.getType()) {
      case INSERT: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.insert(command.getName(), param));
        break;
      }
      case UPDATE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.update(command.getName(), param));
        break;
      }
      case DELETE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.delete(command.getName(), param));
        break;
      }
      case SELECT:
        if (method.returnsVoid() && method.hasResultHandler()) {
          executeWithResultHandler(sqlSession, args);
          result = null;
        } else if (method.returnsMany()) {
          result = executeForMany(sqlSession, args);
        } else if (method.returnsMap()) {
          result = executeForMap(sqlSession, args);
        } else if (method.returnsCursor()) {
          result = executeForCursor(sqlSession, args);
        } else {
          Object param = method.convertArgsToSqlCommandParam(args);
          result = sqlSession.selectOne(command.getName(), param);
          if (method.returnsOptional()
              && (result == null || !method.getReturnType().equals(result.getClass()))) {
            result = Optional.ofNullable(result);
          }
        }
        break;
      case FLUSH:
        result = sqlSession.flushStatements();
        break;
      default:
        throw new BindingException("Unknown execution method for: " + command.getName());
    }
    if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
      throw new BindingException("Mapper method '" + command.getName()
          + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
    }
    return result;
  }

这里之前说过,通过适配器模式,最终的执行sql走的是:mapperMethod.execute(sqlSession, args)
进去这个方法里面,因为我们是一个简单的sql,返回类型就是一个简单的java对象。MapperMethod就是代表了接口中的一个方法,和Mapper.xml中的一个sql语句。(MapperMethod负责将我们java的方法和,xml中定义的一条sql关联映射起来)

MyBatis源码的学习(4)---MapperProxy的invoke方法_第2张图片 以前,刚开始用Mybatis时,习惯不用代理类,直接就是

result = sqlSession.selectOne("learn.UserMapper.selectUser", param);
这样操作。

代码:

public class PubKeyInfoDao extends MyBatisBaseDao{
	
	public  PubKeyInfo findPubKeyInfoByKeyId(PubKeyInfo pubKeyInfo){
		try {
			pubKeyInfo = this.getSqlSession().selectOne(IMyBatisNameDefine.FIND_PUBKEYINFO_BY_ID, pubKeyInfo);
		} catch (Exception e) {
			e.printStackTrace();
		}	
	    return pubKeyInfo;
	} 
}

MyBatis源码的学习(4)---MapperProxy的invoke方法_第3张图片

MyBatis源码的学习(4)---MapperProxy的invoke方法_第4张图片 说明:

  • MappedStatement  MappedStatement维护了一条节点的封装
  • Executor               MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护。

查看我们的执行器,发现执行器是一个:CachingExecutor,而不是我们常说的默认执行器SimpleExecutor,这是为什么?

MyBatis源码的学习(4)---MapperProxy的invoke方法_第5张图片

 

我们的这一步,factory是默认的DefaultSqlSessionFactory类的对象

MyBatis源码的学习(4)---MapperProxy的invoke方法_第6张图片

然后openSession会执行这个方法 :openSessionFromDataSource,这个方法有一步是new一个Executor对象

MyBatis源码的学习(4)---MapperProxy的invoke方法_第7张图片

为这个sqlSession绑定的执行器,先生成SimpleExecutor类型的执行器,然后生成它的包装器类型的CachingExecutor执行器。 

MyBatis源码的学习(4)---MapperProxy的invoke方法_第8张图片

这个参数cacheEnabled:就是我们一般说的二级缓存的开关 ,默认是开启的。

回到我们的代码处:

return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
我们的执行器是CachingExecutor。查看它的query方法

@Override
  public  List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
    BoundSql boundSql = ms.getBoundSql(parameterObject);
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }

第一步生成一个BoundSql对象,第二步生成CacheKey对象,第三步查询操作。

MyBatis源码的学习(4)---MapperProxy的invoke方法_第9张图片

MyBatis源码的学习(4)---MapperProxy的invoke方法_第10张图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Mybatis源码学习)