MyBatis 3.5.4源码之旅八之insert案例分析二
基本流程图:
MapperProxy的invoke做了什么
然后我们看invoke(proxy, method, args, sqlSession);
执行就是我们刚才设置进去的MapperMethod
的执行方法:
MapperMethod的execute
然后进行命令的类型选择,当然我们是Insert
:
然后获取传入的参数:
DefaultSqlSession的insert
调用sqlSession.insert(command.getName(), param)
进行插入内部居然调用的是update
:
DefaultSqlSession的update
@Override
public int update(String statement, Object parameter) {
try {
dirty = true;
MappedStatement ms = configuration.getMappedStatement(statement);
return executor.update(ms, wrapCollection(parameter));
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
然后设置数据为脏数据,从配置对象configuration
中获取MappedStatement
,调用CachingExecutor
执行器的update
方法,之前还会对参数进行包装。
CachingExecutor的update
@Override
public int update(MappedStatement ms, Object parameterObject) throws SQLException {
flushCacheIfRequired(ms);
return delegate.update(ms, parameterObject);
}
先进行缓存的清除:
private void flushCacheIfRequired(MappedStatement ms) {
Cache cache = ms.getCache();
if (cache != null && ms.isFlushCacheRequired()) {
tcm.clear(cache);
}
}
SimpleExecutor的update
然后调用委托执行器SimpleExecutor
的update
,实则是调用了其父类BaseExecutor
的update
:
@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);
}
SimpleExecutor的doUpdate
会先清除本地缓存clearLocalCache
,也就是我们说的一级缓存。然后进行doUpdate
查询:
@Override
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
Statement stmt = null;
try {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
stmt = prepareStatement(handler, ms.getStatementLog());
return handler.update(stmt);
} finally {
closeStatement(stmt);
}
}
Configuration的newStatementHandler
可以看到需要生成一个StatementHandler
,内部做了些工作,重新包装了下,然后放进了拦截链:
其实内部的处理器是PreparedStatementHandler
:
BaseStatementHandler的构造方法
最后调用到了BaseStatementHandler
的构造函数,里面会进行sql
的封装,会创建参数和结果集处理器:
MappedStatement的getBoundSql
内部封了BoundSql
返回。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。