六剑客
。Mybatis3.5
和SpringBoot-2.3.3.RELEASE
。Mybatis的六剑客
,分别是SqlSession
、Executor
、StatementHandler
、ParameterHandler
、ResultSetHandler
、TypeHandler
。语句执行方法
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)
selectOne
和selectList
,从方法名称就很容易知道区别,一个是查询单个,一个是查询多个。如果你对自己的SQL无法确定返回一个还是多个结果的时候,建议使用selectList
。insert
,update
,delete
方法返值是受影响的行数。limit
,如下: 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)
RowBounds
参数中保存了限制的行数,起始行数。立即批量更新方法
List flushStatements()
事务控制方法
void commit()
void commit(boolean force)
void rollback()
void rollback(boolean force)
commit
和 rollback
方法参数中传入 true 值,来保证事务被正常提交(注意,在自动提交模式或者使用了外部事务管理器的情况下,设置 force
值对 session
无效)。大部分情况下你无需调用 rollback()
,因为 MyBatis 会在你没有调用 commit
时替你完成回滚操作。不过,当你要在一个可能多次提交或回滚的 session 中详细控制事务,回滚操作就派上用场了。本地缓存方法
localCacheScope=STATEMENT
来只在语句执行时使用缓存。void clearCache()
获取映射器
T getMapper(Class type)
UserMapper
,如下:UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
DefaultSqlSession
,SqlSessionManager
、SqlSessionTemplate
,其中重要的就是DefaultSqlSession
,这个后面讲到Mybatis执行源码的时候会一一分析。SqlSessionTemplate
,源码如下:@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);
}
}
BaseExecutor
doxxx()
。一级缓存
,因此这里注意下,既然这是个模板类,那么Mybatis执行select的时候默认都会走一级缓存。代码如下: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;
}
CachingExecutor
@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);
}
SimpleExecutor
BatchExecutor
批量更新
操作,由于内部有缓存的实现,使用完成后记得调用flushStatements
来清除缓存。ReuseExecutor
Statement
,省去Statement的重新创建,优化性能。HashMap
来维护Statement对象的。由于当前Map只在该session中有效,所以使用完成后记得调用flushStatements
来清除Map。org.apache.ibatis.session.Configuration
类中,其中创建执行器的源码如下: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;
}
CachingExecutor
,因为默认的cacheEnabled
的值为true
。SimpleStatementHandler
PreparedStatementHandler
CallableStatementHandler
RoutingStatementHandler
ParameterHandler
在Mybatis中负责将sql中的占位符替换为真正的参数,它是一个接口,有且只有一个实现类DefaultParameterHandler
。setParameters
是处理参数最核心的方法。这里不再详细的讲,后面会讲到。JSON
字符串的形式存入数据库,此时就可以自定义一个类型处理器。Cursor
。DefaultResultSetHandler
,其实现的步骤就是将Statement执行后的结果集,按照Mapper文件中配置的ResultType或ResultMap来封装成对应的对象,最后将封装的对象返回。