因为mybatis和spring的集成包当中扩展了一个类SqlSessionTemplate,这个类替代了原来的DefaultSqlSession,SqlSessionTemplate当中的所有查询方法不是直接查询,而是经过一个代理对象,代理对象增强了查询方法,主要是关闭了session
DefaultSqlSession类
@Override
public
<E
> List
<E
> selectList
(String statement, Object parameter
) {
return this.selectList
(statement, parameter, RowBounds.DEFAULT
);
}
@Override
public
<E
> List
<E
> selectList
(String statement, Object parameter, RowBounds rowBounds
) {
try
{
MappedStatement ms
= configuration.getMappedStatement
(statement
);
return executor.query
(ms, wrapCollection
(parameter
), rowBounds, Executor.NO_RESULT_HANDLER
);
} catch
(Exception e
) {
throw ExceptionFactory.wrapException
("Error querying database. Cause: " + e, e
);
} finally
{
ErrorContext.instance
().reset
();
}
}
SqlSessionTemplate类
/**
*
{@inheritDoc
}
*/
@Override
public
<E
> List
<E
> selectList
(String statement, Object parameter
) {
return this.sqlSessionProxy.selectList
(statement, parameter
);
}
/**
* Proxy needed to route MyBatis method calls to the proper SqlSession got from Spring's Transaction Manager It also
* unwraps exceptions thrown by
{@code Method
*
{@code PersistenceExceptionTranslator
}.
*/
private class SqlSessionInterceptor implements InvocationHandler
{
@Override
public Object invoke
(Object proxy, Method method, Object
[] args
) throws Throwable
{
SqlSession sqlSession
= getSqlSession
(SqlSessionTemplate.this.sqlSessionFactory,
SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator
);
try
{
Object result
= method.invoke
(sqlSession, args
);
if (!isSqlSessionTransactional
(sqlSession, SqlSessionTemplate.this.sqlSessionFactory
)) {
// force commit even on non-dirty sessions because some databases require
// a commit/rollback before calling close
()
sqlSession.commit
(true
);
}
return result
;
} catch
(Throwable t
) {
Throwable unwrapped
= unwrapThrowable
(t
);
if (SqlSessionTemplate.this.exceptionTranslator
!= null
&& unwrapped instanceof PersistenceException
) {
// release the connection to avoid a deadlock
if the translator is no loaded. See issue
closeSqlSession
(sqlSession, SqlSessionTemplate.this.sqlSessionFactory
);
sqlSession
= null
;
Throwable translated
= SqlSessionTemplate.this.exceptionTranslator
.translateExceptionIfPossible
((PersistenceException
) unwrapped
);
if (translated
!= null
) {
unwrapped
= translated
;
}
}
throw unwrapped
;
} finally
{
if (sqlSession
!= null
) {
//关闭session
closeSqlSession
(sqlSession, SqlSessionTemplate.this.sqlSessionFactory
);
}
}
}
}
一级缓存其实通俗地来讲就是,在sqlsession里面创建一个本地缓存,然后第二次进行相同的查询时候,就不会到数据库里面进行查找。在spring整合mbatis时,扩展类SqlSessionTemplate在每次执行完一条sql后,都会关闭session,所以一级缓存就会失效