MyBatis-06-Spring的SqlSession和原始区别

DefaultSqlSession

这个就不说了,SQL 执行是调用执行器 Executor 执行

SqlSessionTemplate

构造函数,虽然没有立即创建 SqlSession 传入代理拦截器 SqlSessionInterceptor,但是拦截器是一个实例内部类,可以访问到 SqlSessionFactory
并且 SqlSessionTemplate 不支持 commit、rollback、close 操作(UnsupportedOperationException)

public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
    PersistenceExceptionTranslator exceptionTranslator) {

  notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
  notNull(executorType, "Property 'executorType' is required");

  this.sqlSessionFactory = sqlSessionFactory;
  this.executorType = executorType;
  this.exceptionTranslator = exceptionTranslator;
  this.sqlSessionProxy = (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(),
      new Class[] { SqlSession.class }, new SqlSessionInterceptor());
}

执行时,以 selectOne 举例,是代理到 SqlSessionProxy 处理的,而 SqlSessionProxy 会先从 Spring 的事务上下文获取 SqlSession,没有获取到就新建 SqlSession 并绑定到事务上下文
本质上还是使用 DefaultSqlSession 来处理,并且若是在 Spring 事务管理下,则执行过后不会提交

SqlSessionInterceptor

SqlSessionProxy 的拦截

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 #22
        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) {
        closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
      }
    }
  }
}
posted @ 2024-04-16 22:44  YangDanMua  阅读(13)  评论(0编辑  收藏  举报