Mybatis源码阅读之三

    由前面的系列二分析到MapperMethod的execute方法,咱们接着分析MapperMethod。以下List-1:java

    List-1sql

public class MapperMethod {

  private final SqlCommand command;
  private final MethodSignature method;

  public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
    this.command = new SqlCommand(config, mapperInterface, method);
    this.method = new MethodSignature(config, mapperInterface, method);
  }

  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);
        }
        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;
  }
...

    List-1中,根据类型来调用不一样的处理,咱们以insert为例子分析,调用的就是以下的List-2,首先将传入Mapper方法上的参数转换为SQL参数,以后调用SqlSession的insert方法,注意这个SqlSession是SqlSessionTemplate,咱们来看SqlSessionTemplate的insert方法,如List-3:设计模式

    List-2缓存

case INSERT: {
    Object param = method.convertArgsToSqlCommandParam(args);
    result = rowCountResult(sqlSession.insert(command.getName(), param));
    break;
}

    List-3mybatis

public int insert(String statement, Object parameter) {
    return this.sqlSessionProxy.insert(statement, parameter);
}

以下图1所示,app

                                                             图1this

  •     步骤2调用的SqlSessionInterceptor是JDK的代理类;
  •     步骤4中,作了不少事情,好比不一样类型Executor的生成就是在里面;
  •     步骤13中,会先清空缓存——由于咱们目前看的是insert更新操做;
  •     步骤17中调用的StatementHandler默认是RoutingStatementHandler,用了Delegate设计模式,默认状况下委托给PreparedStatementHandler;
  •     步骤23中,涉及了KeyGenerator,因此后面看mybatis中返还主键值看这里;

    步骤17中,RoutingStatementHandler使用了代理模式,将事情所有委托给第三方来作。设计

    步骤1中调用的SqlSessionTemplate,以Template结尾,看着像使用Template模板模式,可是我的以为是使用了代理模式,由于它内部实现上,大部分事情都委托给了内部类SqlSessionInterceptor。代理

    值得一提的是,BaseExecutor使用了Template模板模式,定义了执行步骤,而后具体实现由其实现类了实现。code

    图1的过程当中,涉及了事物,使用的是Spring的事物管理。

相关文章
相关标签/搜索