executor包执行器功能
作者:灰太狼_cxh 时间:2023-07-26 21:07:36
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 = boundSql.getAdditionalParameter(propertyName);
} else if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else {
MetaObject metaObject = configuration.newMetaObject(parameterObject);
value = metaObject.getValue(propertyName);
}
cacheKey.update(value);
}
}
if (configuration.getEnvironment() != null) {
cacheKey.update(configuration.getEnvironment().getId());
}
return cacheKey;
}
}
BaseExecutor有四个实现类:
CloseExecutor
:仅表明自身已经关闭的执行器,没有其他实际功能SimpleExecutor
: 一个最为简单的执行器BatchExecutor
:支持批量执行功能的执行器ReuseExecutor
: 支持Statement对象复用的执行器。
SimpleExecutor
,BatchExecutor
,ReuseExecutor
这三个执行器的选择是在mybatis
的配置文件中进行的,可选的值由session
包中的ExecutorType定义,这三个执行器主要基于StatementHandler完成创建Statement对象,绑定参数等工作。
来源:https://blog.51cto.com/u_13321676/5015643
标签:executor,包,执行器,功能
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
IDEA将Maven项目中指定文件夹下的xml等文件编译进classes的方法
2023-05-07 07:34:50
![](https://img.aspxhome.com/file/2023/6/122286_0s.png)
java实现学籍管理系统
2023-04-03 00:32:19
C++类常量和类枚举
2022-05-05 17:07:47
![](https://img.aspxhome.com/file/2023/6/109786_0s.jpg)
c#的dllimport使用方法详解
2023-04-20 04:01:49
Android使用Xutils3进行断点下载的实例
2021-08-13 21:59:27
C#如何Task执行任务,等待任务完成
2022-03-06 11:31:31
![](https://img.aspxhome.com/file/2023/2/119452_0s.jpg)
一文详解Java中流程控制语句
2023-11-26 11:39:49
springboot项目启动慢的问题排查方式
2023-06-19 18:58:40
![](https://img.aspxhome.com/file/2023/0/57590_0s.png)
Java 格式化输出JSON字符串的2种实现操作
2023-11-13 09:41:10
java实现顺时针打印矩阵
2023-06-26 19:17:22
ibatis学习之搭建Java项目
2021-11-02 00:35:29
利用Java8 Optional类优雅如何地解决空指针问题
2023-07-30 04:58:13
C#在运行时动态创建类型的实现方法
2023-08-26 21:51:17
Android 消息队列模型详解及实例
2023-04-06 10:49:43
![](https://img.aspxhome.com/file/2023/2/137472_0s.png)
利用json2POJO with Lombok 插件自动生成java类的操作
2023-07-12 09:31:28
![](https://img.aspxhome.com/file/2023/8/69718_0s.jpg)
C# 系统热键注册实现代码
2021-10-07 00:12:14
Java实现仿淘宝滑动验证码研究代码详解
2022-12-28 00:51:11
![](https://img.aspxhome.com/file/2023/3/74893_0s.png)
c# HttpWebRequest通过代理服务器抓取网页内容应用介绍
2023-04-04 20:10:35
Unity 静态变量跨场景操作
2023-10-16 14:32:41
![](https://img.aspxhome.com/file/2023/5/119545_0s.jpg)
B/S与C/S架构的区别介绍
2023-07-02 13:24:33