任何一个技术都不能浅尝辄止,今天作者就带大家深入底层源码看一看Mybatis的基础架构。此篇文章只是源码的入门篇,讲一些Mybatis中重要的组件,作者称之为六剑客。
T selectOne(String statement, Object parameter) List selectList(String statement, Object parameter) Cursor selectCursor(String statement, Object parameter) Map selectMap(String statement, Object parameter, String mapKey)int insert(String statement, Object parameter)int update(String statement, Object parameter)int delete(String statement, Object parameter)
List selectList (String statement, Object parameter, RowBounds rowBounds) Cursor selectCursor(String statement, Object parameter, RowBounds rowBounds) Map selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)void select (String statement, Object parameter, ResultHandler handler)void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler handler)
List flushStatements()
void commit()void commit(boolean force)void rollback()void rollback(boolean force)
void clearCache()
T getMapper(Class type)
UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
@Bean @ConditionalOnMissingBean public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) //根据执行器的类型创建不同的执行器,默认CachingExecutor ExecutorType executorType = this.properties.getExecutorType(); if (executorType != null) { return new SqlSessionTemplate(sqlSessionFactory, executorType); } else { return new SqlSessionTemplate(sqlSessionFactory); } }
private List queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { List list; //此处的localCache即是一级缓存,是一个Map的结构 localCache.putObject(key, EXECUTION_PLACEHOLDER); try { //执行真正的查询 list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql); } finally { localCache.removeObject(key); } localCache.putObject(key, list); if (ms.getStatementType() == StatementType.CALLABLE) { localOutputParameterCache.putObject(key, parameter); } return list; }
@Override public List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { //查看当前Sql是否使用了二级缓存 Cache cache = ms.getCache(); //使用缓存了,直接从缓存中取 if (cache != null) { flushCacheIfRequired(ms); if (ms.isUseCache() && resultHandler == null) { ensureNoOutParams(ms, boundSql); @SuppressWarnings("unchecked") //从缓存中取数据 List list = (List) tcm.getObject(cache, key); if (list == null) { //没取到数据,则执行SQL从数据库查询 list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); //查到了,放入缓存中 tcm.putObject(cache, key, list); // issue #578 and #116 } //直接返回 return list; } } //没使用二级缓存,直接执行SQL从数据库查询 return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); }
public Executor newExecutor(Transaction transaction, ExecutorType executorType) { //没有指定执行器的类型,创建默认的,即是SimpleExecutor executorType = executorType == null ? defaultExecutorType : executorType; executorType = executorType == null ? ExecutorType.SIMPLE : executorType; Executor executor; //类型是BATCH,创建BatchExecutor if (ExecutorType.BATCH == executorType) { executor = new BatchExecutor(this, transaction); //类型为REUSE,创建ReuseExecutor } else if (ExecutorType.REUSE == executorType) { executor = new ReuseExecutor(this, transaction); } else { //除了上面两种,创建的都是SimpleExecutor executor = new SimpleExecutor(this, transaction); } //如果全局配置了二级缓存,则创建CachingExecutor,SpringBoot中这个参数默认是true,可以自己设置为false if (cacheEnabled) { //创建CachingExecutor executor = new CachingExecutor(executor); } executor = (Executor) interceptorChain.pluginAll(executor); return executor; }