由前面的系列二分析到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
步驟17中,RoutingStatementHandler使用了代理模式,將事情所有委託給第三方來作。設計
步驟1中調用的SqlSessionTemplate,以Template結尾,看着像使用Template模板模式,可是我的以爲是使用了代理模式,由於它內部實現上,大部分事情都委託給了內部類SqlSessionInterceptor。代理
值得一提的是,BaseExecutor使用了Template模板模式,定義了執行步驟,而後具體實現由其實現類了實現。code
圖1的過程當中,涉及了事物,使用的是Spring的事物管理。