1,spring-mybatis一级缓存失效,因为是sqlsesstionTemplate,其使用了一个代理proxysession,每次请求都会关闭session;
spring-mybatis扩展了一个类sqlsessiontemplate,这个类在spring容器启动时被注入给mapper, 这个类替代了原来的mybatis的DefaultSqlSession,sqlsessiontemplate的所有查询并不直接查询,而是经过一个代理对象,代理对象增加了查询方法,主要是每次关闭了session
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {
Assert.notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
Assert.notNull(executorType, "Property 'executorType' is required");
this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType;
this.exceptionTranslator = exceptionTranslator;
this.sqlSessionProxy = (SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionTemplate.SqlSessionInterceptor());
}
............
private class SqlSessionInterceptor implements InvocationHandler {
private SqlSessionInterceptor() {
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
SqlSession sqlSession = SqlSessionUtils.getSqlSession(SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
Object unwrapped;
try {
Object result = method.invoke(sqlSession, args);//其中sqlsession是mybatis的defaultSession,加了代理是为增加关闭功能
if (!SqlSessionUtils.isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
sqlSession.commit(true);
}
unwrapped = result;
} catch (Throwable var11) {
unwrapped = ExceptionUtil.unwrapThrowable(var11);
if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
sqlSession = null;
Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException)unwrapped);
if (translated != null) {
unwrapped = translated;
}
}
throw (Throwable)unwrapped;
} finally {
if (sqlSession != null) { //每次都会关闭
SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
}
}
return unwrapped;
}
}
2,mybatis的sqlsession是defaultSqlSession,是实类,同一个session不关闭,直到结束,session暴露在代码,可以随时close, 相当于关闭session可控
而spring-mybatis的每次session要关闭是因为session不在ioc容器中,加上集成后无接口关闭session,没暴露api,所以使用代理增加了关闭session, 所以为了资源的可重复利用,防止不关,每次要关闭
来源:CSDN
作者:xiaoza7
链接:https://blog.csdn.net/xiaoza7/article/details/104592578