【Mybatis源码阅读】mapper的执行原理

mybatis专栏 https://blog.csdn.net/worn_xiao/category_6530299.html?spm=1001.2014.3001.5482

好了Mybatis具体的执行流程是怎么样的呢。我们先从一个例子开始

点getMapper点进去看

你会发现实际上是从configuration中获取一个mapper的对象出来。具体mapper怎么注册到configuration中的,请自行查看我前面关于configuration中的文章。

再往下走就是mapperRegistry,这个映射就是mapper的注册类,在mybaties初始化的时候注册了mapper。这个mapper通过类扫面,放到了mapperRegistry中。

如上代码所示获取mapper的时候,实际上是获取一个mapper的代理,然而则个代理就是在初始话的时候,代理到内存的。那么根据代码很容易知道。实际上就是通过代理的工厂,创建除实际的代理来。执行mapper的时候,执行的是Mapper的代理。

再往下看,可以看到通过newInstance()方法获取到一个MapperProxy的代理,然后通过代理执行mapper的方法。那么代理做了什么呢。我们点进代理看

实际上就是获取到mapper映射的方法。然后执行mapper的方法。好了那么这个MapperMethod又做了什么,我们看一下mapperMethod.execute()。

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

好了看到了上面的代码以后,我们是不是可以看到sqlSession了,那么sqlSession是从哪里来的呢。我们来看一下下面的代码

这里就是入口,实际上这个就是我们之前说的SqlSession。然后的话大家应该知道后续是怎么执行的了。我之前写过一篇sqlSession执行流程的文章。总的来说一句话。Mapper就是基于SqlSession执行流程之上进行封装而得到的。

如上图 我们点进去看 可以看到,方法的参数,然后调用sqlSession进行执行。

如上图所示。接下来的流程我就不讲了。你可以看我上一篇博客。先了解Sqlsession的执行流程。


版权声明:本文为worn_xiao原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。