zoukankan      html  css  js  c++  java
  • mybatis源码分析(2)-----SqlSession创建

    1. 在创建好sqlSessionFactory之后,接着就要配置sqlSession的创建。

    <bean id="simpleTempalte" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
        <constructor-arg index="1" value="SIMPLE" />
    </bean>
    • 构造参数,包括sqlSessionFactory对象,以及ExecutorType(simple)

    2. sqlSession接口

    • 我们的应用程序,是直接注入sqlSessionTemplate ,操作数据库
    simpleTempalte.delete(Statement.getStatement(CxCaseMapper.class, "deleteById"), id);
    • 实现类sqlSessionTemplate
    public class SqlSessionTemplate implements SqlSession {
      //session 工场的引用
      private final SqlSessionFactory sqlSessionFactory;
      // 对于数据库的操作类型
      private final ExecutorType executorType;
      //sqlSession代理
      private final SqlSession sqlSessionProxy;
      private final PersistenceExceptionTranslator exceptionTranslator;
    }
    • sqlSession对每一个数据库的操作,实际上是引用代理对象sqlSessionProxy 对于目标方法的执行。
      @Override
      public int delete(String statement) {
        return this.sqlSessionProxy.delete(statement);
      }
    • 在构造方法中,给代理对象已经其他属性赋予的默认值
        public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
          PersistenceExceptionTranslator exceptionTranslator) {
        this.sqlSessionFactory = sqlSessionFactory;
        this.executorType = executorType;
        this.exceptionTranslator = exceptionTranslator;
    //构造代理对象
    this.sqlSessionProxy = (SqlSession) newProxyInstance( SqlSessionFactory.class.getClassLoader(), new Class[] { SqlSession.class }, new SqlSessionInterceptor()); } private class SqlSessionInterceptor implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //这里获取的sqlSession 其实是DefaultSqlSession SqlSession sqlSession
    = getSqlSession( SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator); try {
    // 代理对象对于目标对象的调用,其实是defaultSqlSession 对于目标方法的调用 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) {
    //调用目标方法后,关闭Session。 后续会重点讲解 closeSqlSession(sqlSession, SqlSessionTemplate.
    this.sqlSessionFactory); } } } }
    •  defaultSqlSession 对于目标方法的执行
    public class DefaultSqlSession implements SqlSession {
    
      private Configuration configuration;
      private Executor executor;
    
      private boolean autoCommit;
      private boolean dirty;
    
      @Override
      public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
        try {
          MappedStatement ms = configuration.getMappedStatement(statement);
          executor.query(ms, wrapCollection(parameter), rowBounds, handler);
        } catch (Exception e) {
          throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
        } finally {
          ErrorContext.instance().reset();
        }
      }
    
    }

    3.   代理的优点

      无论是多个dao使用一个SqlSessionTemplate,还是一个dao使用一个SqlSessionTemplate,SqlSessionTemplate都是对应一个sqlSession,当多个web线程调用同一个dao时,它们使用的是同一个SqlSessionTemplate,也就是同一个SqlSession,保证线程安全,

    4 .总结

  • 相关阅读:
    Putty·Network error:Software caused connection abort
    VSCode·搭建Java开发环境
    MSSQL·将一对多的数据合并为以指定分隔符的数据
    技能Get·Windows10将任何格式文件固定到开始屏幕
    MSSQL·查询TSQL语句执行时间的三种方法
    Javac·编码GBK的不可映射字符
    傅里叶变换、拉氏变换、z变换的含义
    宏、内联函数和普通函数的区别
    OpenGL中创建GLUT菜单
    在PC安裝Android系統+軟體
  • 原文地址:https://www.cnblogs.com/chihirotan/p/6591722.html
Copyright © 2011-2022 走看看