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, 所以爲了資源的可重複利用,防止不關,每次要關閉