#yyds干货盘点# executor包(执行器功能)

最是人间留不住,朱颜辞镜花辞树。这篇文章主要讲述#yyds干货盘点# executor包(执行器功能)相关的知识,希望能为你提供帮助。
executor包(执行器功能)
executor包中的各个子包提供的功能,最终这些功能都由Executor接口及其实现类共同对外提供服务。Executor接口基于以下方法可以完成增,删,改查以及事务处理等操作。事实上,mybatis中的所有数据库操作是通过调用这些方法实现的。

public interface Executor

ResultHandler NO_RESULT_HANDLER = null;

// 数据更新操作,其中数据的增加、删除、更新均可由该方法实现
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;
// 数据查询操作,返回结果为列表形式
/**
* 执行查询操作
* @param ms 映射语句对象
* @param parameter 参数对象
* @param rowBounds 翻页限制
* @param resultHandler 结果处理器
* @param < E> 输出结果类型
* @return 查询结果
* @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;
// 创建当前查询的缓存键值
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();
// 关闭执行器
void close(boolean forceRollback);
// 判断执行器是否关闭
boolean isClosed();
// 设置执行器包装
void setExecutorWrapper(Executor executor);


BaseExecutor是一个抽象类,并用到了模板模式,实现了其子类的一些共有的基础功能,而将与子类直接相关的操作交给子类处理。
public abstract class BaseExecutor implements Executor

private static final Log log = LogFactory.getLog(BaseExecutor.class);

protected Transaction transaction;
protected Executor wrapper;

protected ConcurrentLinkedQueue< DeferredLoad> deferredLoads;
// 查询操作的结果缓存
protected PerpetualCache localCache;
// Callable查询的输出参数缓存
protected PerpetualCache localOutputParameterCache;
protected Configuration configuration;

protected int queryStack;
private boolean closed;




/**
* 更新数据库数据,INSERT/UPDATE/DELETE三种操作都会调用该方法
* @param ms 映射语句
* @param parameter 参数对象
* @return 数据库操作结果
* @throws SQLException
*/
@Override
public int update(MappedStatement ms, Object parameter) throws SQLException
ErrorContext.instance().resource(ms.getResource())
.activity("executing an update").object(ms.getId());
if (closed)
// 执行器已经关闭
throw new ExecutorException("Executor was closed.");

// 清理本地缓存
clearLocalCache();
// 返回调用子类进行操作
return doUpdate(ms, parameter);




/**
* 执行查询操作
* @param ms 映射语句对象
* @param parameter 参数对象
* @param rowBounds 翻页限制
* @param resultHandler 结果处理器
* @param < E> 输出结果类型
* @return 查询结果
* @throws SQLException
*/
@Override
public < E> List< E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException
BoundSql boundSql = ms.getBoundSql(parameter);
// 生成缓存的键
CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
return query(ms, parameter, rowBounds, resultHandler, key, boundSql);


/**
* 查询数据库中的数据
* @param ms 映射语句
* @param parameter 参数对象
* @param rowBounds 翻页限制条件
* @param resultHandler 结果处理器
* @param key 缓存的键
* @param boundSql 查询语句
* @param < E> 结果类型
* @return 结果列表
* @throws SQLException
*/
@SuppressWarnings("unchecked")
@Override
public < E> List< E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException
ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
if (closed)
// 执行器已经关闭
throw new ExecutorException("Executor was closed.");

if (queryStack == 0 & & ms.isFlushCacheRequired())// 新的查询栈且要求清除缓存
// 清除一级缓存
clearLocalCache();

List< E> list;
try
queryStack++;
// 尝试从本地缓存获取结果
list = resultHandler == null ? (List< E> ) localCache.getObject(key) : null;
if (list != null)
// 本地缓存中有结果,则对于CALLABLE语句还需要绑定到IN/INOUT参数上
handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
else
// 本地缓存没有结果,故需要查询数据库
list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);

finally
queryStack--;

if (queryStack == 0)
// 懒加载操作的处理
for (DeferredLoad deferredLoad : deferredLoads)
deferredLoad.load();

deferredLoads.clear();
// 如果本地缓存的作用域为STATEMENT,则立刻清除本地缓存
if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT)
clearLocalCache();


return list;




/**
* 生成查询的缓存的键
* @param ms 映射语句对象
* @param parameterObject 参数对象
* @param rowBounds 翻页限制
* @param boundSql 解析结束后的SQL语句
* @return 生成的键值
*/
@Override
public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql)
if (closed)
throw new ExecutorException("Executor was closed.");

// 创建CacheKey,并将所有查询参数依次更新写入
CacheKey cacheKey = new CacheKey();
cacheKey.update(ms.getId());
cacheKey.update(rowBounds.getOffset());
cacheKey.update(rowBounds.getLimit());
cacheKey.update(boundSql.getSql());
List< ParameterMapping> parameterMappings = boundSql.getParameterMappings();
TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry();
for (ParameterMapping parameterMapping : parameterMappings)
if (parameterMapping.getMode() != ParameterMode.OUT)
Object value;
String propertyName = parameterMapping.getProperty();
if (boundSql.hasAdditionalParameter(propertyName))
value = https://www.songbingjia.com/android/boundSql.getAdditionalParameter(propertyName);
else if (parameterObject == null)
value = https://www.songbingjia.com/android/null;
else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()))
value = https://www.songbingjia.com/android/parameterObject;
else
MetaObject metaObject = configuration.newMetaObject(parameterObject);
value = https://www.songbingjia.com/android/metaObject.getValue(propertyName);

cacheKey.update(value);


if (configuration.getEnvironment() != null)
cacheKey.update(configuration.getEnvironment().getId());

return cacheKey;


BaseExecutor有四个实现类:
【#yyds干货盘点# executor包(执行器功能)】CloseExecutor :仅表明自身已经关闭的执行器,没有其他实际功能

SimpleExecutor : 一个最为简单的执行器

BatchExecutor :支持批量执行功能的执行器

ReuseExecutor : 支持Statement对象复用的执行器。

SimpleExecutor,BatchExecutor,ReuseExecutor 这三个执行器的选择是在mybatis的配置文件中进行的,可选的值由session包中的ExecutorType定义,这三个执行器主要基于StatementHandler完成创建Statement对象,绑定参数等工作。





    推荐阅读