5.1.1.2 CachingExecutor执行器
接着进到 CachingExecutor.query 方法
java
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
// 首先也要拿到BoundSql,这个直接看章节`5.1.1.1-1`和`5.1.1.1-2`
BoundSql boundSql = ms.getBoundSql(parameterObject);
// 这一步参考章节`5.1.1.1-3`
CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
// 查询,继续往下看
return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
// 取出mapper对应的二级缓存的实现对象,二级缓存是全局性的,一级缓存是会话级/请求级
Cache cache = ms.getCache();
if (cache != null) {
// 如果设置了该语句 flushCache="true" ,那么执行前要清空缓存先
flushCacheIfRequired(ms);
// 如果该语句设置了 useCache="true" ,就是要走缓存的意思,同时 resultHandler 为空,也就是说处理结果交给mybatis,必须两个条件都符合
if (ms.isUseCache() && resultHandler == null) {
ensureNoOutParams(ms, boundSql);
@SuppressWarnings("unchecked")
// 先从缓存中取值(注意:没有commit的结果不会存到缓存中,这一点也是与一级缓存不同的地方)
List<E> list = (List<E>) tcm.getObject(cache, key);
if (list == null) {
// 缓存中没值,就执行查询,参考章节`5.1.1.1-4`
list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
// 查到了值,放二级缓存中
tcm.putObject(cache, key, list); // issue #578 and #116
}
return list;
}
}
// 参考章节`5.1.1.1-4`
return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
5.1.2 insert
Mybatis默认提供的SqlSession实现类是DefaultSqlSession,那直接进入这个类
java
/**
statement:对应mapper配置中的语句id
parameter:传参
*/
public int insert(String statement, Object parameter) {
// 调用的是update方法
return update(statement, parameter);
}
public int update(String statement, Object parameter) {
try {
dirty = true;
// 取出 MappedStatement 对象
MappedStatement ms = configuration.getMappedStatement(statement);
// 为啥insert 是用的执行器的update方法呢,因为 Executor 接口中就没有定义 insert 方法,所以cud,都是走的update方法,r 则走的是 query方法。
return executor.update(ms, wrapCollection(parameter));
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
executor.update 方法,这里指的是CachingExecutor类的update方法
java
public int update(MappedStatement ms, Object parameterObject) throws SQLException {
// 有必要(该语句 flushCache="true" )则清空缓存
flushCacheIfRequired(ms);
// 这一步走到BaseExecutor.update方法
return delegate.update(ms, parameterObject);
}
BaseExecutor类的update方法
java
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();
// 子类实现 doUpdate 方法,这里是指 SimpleExecutor 子类
return doUpdate(ms, parameter);
}
SimpleExecutor类的doUpdate方法
java
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
Statement stmt = null;
try {
// 拿到 configuration 对象
Configuration configuration = ms.getConfiguration();
// 拿到 StatementHandler,这个对象就是真正跟jdbc打交道的,封装了jdbc对数据的操作,详情解析看章节`第六章`,以下执行流程都放在`第六章`讲解
StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
// 预处理操作
stmt = prepareStatement(handler, ms.getStatementLog());
// 执行操作
return handler.update(stmt);
} finally {
closeStatement(stmt);
}
}