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关联映射起来)
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;
}
}
查看我们的执行器,发现执行器是一个:CachingExecutor,而不是我们常说的默认执行器SimpleExecutor,这是为什么?
我们的这一步,factory是默认的DefaultSqlSessionFactory类的对象
然后openSession会执行这个方法 :openSessionFromDataSource,这个方法有一步是new一个Executor对象
为这个sqlSession绑定的执行器,先生成SimpleExecutor类型的执行器,然后生成它的包装器类型的CachingExecutor执行器。
这个参数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对象,第三步查询操作。