六剑客
。Mybatis3.5
和SpringBoot-2.3.3.RELEASE
。Mybatis的六剑客
,分别是SqlSession
、Executor
、StatementHandler
、ParameterHandler
、ResultSetHandler
、TypeHandler
。<T> T selectOne(String statement, Object parameter)
<E> List<E> selectList(String statement, Object parameter)
<T> Cursor<T> selectCursor(String statement, Object parameter)
<K,V> Map<K,V> 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
,如下:<E> List<E> selectList (String statement, Object parameter, RowBounds rowBounds)
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)
void select (String statement, Object parameter, ResultHandler<T> handler)
void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler<T> handler)
RowBounds
参数中保存了限制的行数,起始行数。List<BatchResult> 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> T getMapper(Class<T> 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);
}
}
doxxx()
。一级缓存
,因此这里注意下,既然这是个模板类,那么Mybatis执行select的时候默认都会走一级缓存。代码如下:private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
List<E> 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 <E> List<E> 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<E> list = (List<E>) 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);
}
批量更新
操作,由于内部有缓存的实现,使用完成后记得调用flushStatements
来清除缓存。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
。ParameterHandler
在Mybatis中负责将sql中的占位符替换为真正的参数,它是一个接口,有且只有一个实现类DefaultParameterHandler
。setParameters
是处理参数最核心的方法。这里不再详细的讲,后面会讲到。JSON
字符串的形式存入数据库,此时就可以自定义一个类型处理器。Cursor
。DefaultResultSetHandler
,其实现的步骤就是将Statement执行后的结果集,按照Mapper文件中配置的ResultType或ResultMap来封装成对应的对象,最后将封装的对象返回。联系客服