MyBatis 3.5.4源码之旅八之insert案例分析二
- 基本流程图:
- MapperProxy的invoke做了什么
- MapperMethod的execute
- DefaultSqlSession的insert
- DefaultSqlSession的update
- CachingExecutor的update
- SimpleExecutor的update
- SimpleExecutor的doUpdate
- Configuration的newStatementHandler
- BaseStatementHandler的构造方法
- MappedStatement的getBoundSql
基本流程图:
MapperProxy的invoke做了什么
然后我们看invoke(proxy, method, args, sqlSession);
执行就是我们刚才设置进去的MapperMethod
的执行方法:
MapperMethod的execute
然后进行命令的类型选择,当然我们是Insert
:
然后获取传入的参数:
DefaultSqlSession的insert
调用sqlSession.insert(command.getName(), param)
进行插入内部居然调用的是update
:
DefaultSqlSession的update
@Overridepublic 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
@Overridepublic 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
:
@Overridepublic 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
查询:
@Overridepublic 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
返回。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。