Executor 是MyBatis的核心接口之一,其中定义了数据库操作的基本方法。在实际应用中经常设计的SqlSession接口的功能,都是基于Executor接口实现的。
SQL 语句的执行涉及多个组件,包括 MyBatis 的四大核心,它们是: Executor
、StatementHandler
、ParameterHandler
、ResultSetHandler
。SQL 的执行过程可以用下面这幅图来表示。
MyBatis 层级结构各个组件的介绍:
- SqlSession: ,它是 MyBatis 核心 API,主要用来执行命令,获取映射,管理事务。接收开发人员提供 Statement Id 和参数。并返回操作结果。
- Executor :执行器,是 MyBatis 调度的核心,负责 SQL 语句的生成以及查询缓存的维护。
- StatementHandler : 封装了JDBC Statement 操作,负责对 JDBC Statement 的操作,如设置参数、将Statement 结果集转换成 List 集合。
- ParameterHandler : 负责对用户传递的参数转换成 JDBC Statement 所需要的参数。
- ResultSetHandler : 负责将 JDBC 返回的 ResultSet 结果集对象转换成 List 类型的集合。
- TypeHandler : 用于 Java 类型和 JDBC 类型之间的转换。
- MappedStatement : 动态 SQL 的封装
- SqlSource : 表示从 XML 文件或注释读取的映射语句的内容,它创建将从用户接收的输入参数传递给数据库的 SQL。
- Configuration: MyBatis 所有的配置信息都维持在 Configuration 对象之中。
一、Executor 说明
MyBatis 提供 Executor 接口实现如下图。
在这些 Executor接口实现中涉及两种设计模式:模板模式和装饰器模式。
装饰器模式:二级缓存 CachingExecutor扮演了装饰器的角色,为Executor添加二级缓存功能。
模板模式:BaseExecutor是实现Executor接口的抽象类,其中主要提供了缓存管理和事务管理的基本功能。而其继承其子类只有实现四个方法分别 是: doUpdate()方法、 doQue可()方法、 doQueryCursor()方法、 doFlushStatement()方法,其余的功 能在 BaseExecutor 中实现。
1.1 Executor 接口中定义的方法如下:
/**
* @author Clinton Begin
* Mybatis核心接口之一,定义了数据库操作最基本的方法。
* Session的功能都是基于他来实现。
*/
public interface Executor {
ResultHandler NO_RESULT_HANDLER = null;
//执行增删改的三种类型SQL语句
int update(MappedStatement ms, Object parameter) throws SQLException;
//执行select类型的sql语句,返回结果为集合对象
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
//执行select类型的sql语句,返回结果为集合对象 这个方法在实现类中还是调用上面的方法执行
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
//执行select类型的sql语句,返回结果为游标
<E> Cursor<E> queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;
//批量执行SQL语句
List<BatchResult> flushStatements() throws SQLException;
//提交事务
void commit(boolean required) throws SQLException;
//回滚事务
void rollback(boolean required) throws SQLException;
//创建缓存key值
CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);
//是否缓存
boolean isCached(MappedStatement ms, CacheKey key);
//清空一级缓存
void clearLocalCache();
//延迟加载一级缓存数据
void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);
//获取事务对象
Transaction getTransaction();
//关闭Executor对象
void close(boolean forceRollback);
//对象是否关闭
boolean isClosed();
//
void setExecutorWrapper(Executor executor);
}
1.2 BaseExecutor 抽象类
抽象类,实现了executor接口的大部分方法,主要提供了缓存管理和事务管理的能力,其他子类需要实现的抽象方法doUpdate,doQuery等方法;
下图是BaseExecutor的query()方法执行过程:
BaseExecutor 中各个字段的含义如下:
public abstract class BaseExecutor implements Executor {
private static final Log log = LogFactory.getLog(BaseExecutor.class);
protected Transaction transaction;//事务对象,实现事务的提交、回滚和关闭操作
protected Executor wrapper;//装饰器模式 封装Executor对象
protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;//延迟加载队列
protected PerpetualCache localCache;//一级缓存的实现
protected PerpetualCache localOutputParameterCache;//一级缓存用于缓存输出的结果
protected Configuration configuration;//全局唯一configuration对象的引用
protected int queryStack;//用于嵌套查询的的层数
private boolean closed;
protected BaseExecutor(Configuration configuration, Transacti