从上篇动态代理对象的方法都调用MapperMethod.execute()中可知,执行不同等SQL命令最终会使用数据库会话对象SqlSession来执行不同的SQL脚本,对应方法如下:
- INSERT:sqlSession.insert();
- UPDATE:sqlSession.update();
- DELETE:sqlSession.delete();
- SELECT:sqlSession.select() / sqlSession.selectList() / sqlSession.selectCursor() / sqlSession.selectMap()。
// MapperProxy 源码
package org.apache.ibatis.binding;
public class MapperMethod {
// 如SELECT命名里面查询不同的数目的数据
// executeForMany() 、 executeForCursor() 、executeForMap()等
private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
List<E> result;
Object param = method.convertArgsToSqlCommandParam(args);
if (method.hasRowBounds()) {
RowBounds rowBounds = method.extractRowBounds(args);
// 执行sql脚本,返回结果对象
result = sqlSession.selectList(command.getName(), param, rowBounds);
} else {
// 执行sql脚本,返回结果对象
result = sqlSession.selectList(command.getName(), param);
}
// issue #510 Collections & arrays support
if (!method.getReturnType().isAssignableFrom(result.getClass())) {
if (method.getReturnType().isArray()) {
return convertToArray(result);
} else {
return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
}
}
return result;
}
}
而接口类SqlSession具体的实现类为DefaultSqlSession,其中DefaultSqlSession中存储了执行器对象Executor executor,用来执行SQL脚本,为Executor为构造DefaultSqlSession构造函数入参传入,所以在生成DefaultSqlSession示例之前需要提供SQL脚本的执行器。
// DefaultSqlSession 源码
package org.apache.ibatis.session.defaults;
// 查询列表
private <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
try {
// 获取MappedStatement对象
MappedStatement ms = configuration.getMappedStatement(statement);
// Sql执行器执行sql,传入MappedStatement对象、执行参数、RowBounds对象,结果处理器
return executor.query(ms, wrapCollection(parameter), rowBounds, handler);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
DefaultSqlSession实例的通过过工厂模式DefaultSqlSessionFactory类的openSession生成,其中在new DefaultSqlSession(configuration, executor, autoCommit);之前可以看到Executor执行器通过configuration.newExecutor(tx, execType)实例化。
// DefaultSqlSessionFactory 源码
package org.apache.ibatis.session.defaults;
public class DefaultSqlSessionF