继续sqlSession运行过程分析,上一篇文章讲到通过sqlSession中executor对象的query方法执行的查询,在分析这个方法的源码之前,先分析下SqlSession执行sql中用到的比较重要的几个对象。SqlSession中是通过Executor 、StatementHandler、ParameterHandler、ResultHandler来完成数据库操作和结果返回的。先稍微来了解下这几个对象大致的作用:
- Executor:代表执行器,由其来调度StatementHandler、ParameterHandler、ResultHandler来执行对应的sql并返回结果。
- StatementHandler:使用数据库的Statement对象(PrepareStatement)完成实际的查询,是四大对象的核心,起到承上启下的作用。
- ParameterHandler:用来sql对参数的处理。
- ResultHandler:对查询返回的结果集(ResultSet)进行封装处理后返回。
下面详细来研究上面提到的四个对象。
1.执行器(Executor)
执行器起(Executor)了至关重要的作用。它是一个真正执行Java和数据库交互的组件,在Mybatis中存在三种类型的执行器,可以在setting属性中配置:
- SIMPLE,简单执行器,不配置它就是默认的执行器。
- REUSE,一种重用预处理语句的执行器。
- BATCH,执行会重用预处理语句和支持批量更新,它是针对批量操作专用的执行器。
他们都提供了查询和更新相关的方法以及相关事务的方法,下面是Executor接口中的部分方法:
int update(MappedStatement ms, Object parameter) throws SQLException;
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
<E> Cursor<E> queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;
List<BatchResult> flushStatements() throws SQLException;
void commit(boolean required) throws SQLException;
void rollback(boolean required) throws SQLException;
下面先不看这些方法的具体实现,而是先来了解下如何来创建Executor,首先sqlSession中关联的Executor对象是在调用SqlSessionFactory.openSession()的时候创建的,具体的代码如下:
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//execType是执行器的类型,在openSession()方法中可以传入; tx是指定的事务类型
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
可以看到Executor对象是通过configuration.newExecutor()方法创建的,传入的两个参数是事务类型和传入的执行器类型;下面来看下这个方法的具体实现:
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
//如果配置了二级缓存,则会创建一个CachingExecutor对当前Executor进行一层包装,这个对象负责执行缓存逻辑
if (cacheEnabled)