zoukankan      html  css  js  c++  java
  • MyBatis的SqlSession理解(二)

    Mybaits加载执行该xml配置

    class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean

     spring 在初始化 sqlsessionbean的时候通过createBean调用了在SqlSessionFactoryBean中实现了接口InitializingBean的afterPropertiesSet()方法在该方法中调用了buildSqlSessionFactory()开始创建SqlSessionFactory

    buildSqlSessionFactory()方法完成以下功能

    一:

    a)    创建configuration

    b)    typeAliasesPackage

    c)    typeAliases TYPE_ALIASES将类型存放到此map里面同b

    d)    plugins configuration添加插件

    e)    typeHandlersPackage

    f)    typeHandlers

    g)    xmlConfigBuilder.parse()将所有的配置从xml中读取并放入到对应的变量里面

    h)    mapperLocations

    二:xmlMapperBuilder.parse()——> configurationElement

    a)    parameterMapElement(context.evalNodes("/mapper/parameterMap"));将mapper.xml中的prameterMap节点的数据添加到configuration.parameterMaps中

    b)    resultMapElements(context.evalNodes("/mapper/resultMap"));将mapper.xml中的resultMap节点的数据添加到configuration.incompleteResultMaps中

    c)    sqlElement(context.evalNodes("/mapper/sql"));

    d)    buildStatementFromContext(select|insert|update|delete);buildStatementFromContext:从mapper 中获取sql语句,执行类型(增删改查),parseStatementNode中addMappedStatement创建每个mapper对应的方法创建MappedStatement并添加到 configuration.mappedStatements.put(com.qb.mysql.dao.TRoleDao.getUserRoleByRid, MappedStatement)

    最后返回了一个 DefaultSqlSessionFactory(config)

    在调用SqlSessionTemplate进行dao层操作时,其会将工作委托给sqlSessionProxy属性进行,而sqlSessionProxy在进行相关method调用时,用到了JDK动态代理机制,首先SqlSessionUtils.getSqlSession获取sqlSession    

     private class SqlSessionInterceptor implements InvocationHandler {
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //返回一个DefaultSqlsession
          SqlSession sqlSession = getSqlSession(
              SqlSessionTemplate.this.sqlSessionFactory,
              SqlSessionTemplate.this.executorType,
              SqlSessionTemplate.this.exceptionTranslator);
          try {
         //调用该类的MapperProxy的invoke方法
            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);
            }
          }
        }
      }
    在getSqlSession方法中创建事务,创建Executor,默认创建SimpleExecutor;InterceptorChain添加拦截器 InterceptorChain.pluginAll()

    SqlSessionTemplate ->SqlSessionInterceptor->SqlSessionUtils. getSqlSession()->(defaultsqlsessionfactory)sessionFactory.openSession()->openSessionFromDataSource()

    MapperProxy的invoke方法的方法
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Object.class.equals(method.getDeclaringClass())) {
          return method.invoke(this, args);
        }
        final MapperMethod mapperMethod = cachedMapperMethod(method);
    //执行execute
        return mapperMethod.execute(sqlSession, args);
      }
    //根据sql类型选择对应的方法
    public Object execute(SqlSession sqlSession, Object[] args) { Object result; if (SqlCommandType.INSERT == command.getType()) { Object param = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.insert(command.getName(), param)); } else if (SqlCommandType.UPDATE == command.getType()) { Object param = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.update(command.getName(), param)); } else if (SqlCommandType.DELETE == command.getType()) { Object param = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.delete(command.getName(), param)); } else if (SqlCommandType.SELECT == command.getType()) { if (method.returnsVoid() && method.hasResultHandler()) { executeWithResultHandler(sqlSession, args); result = null; } else if (method.returnsMany()) { result = executeForMany(sqlSession, args); } else if (method.returnsMap()) { result = executeForMap(sqlSession, args); } else { Object param = method.convertArgsToSqlCommandParam(args); result = sqlSession.selectOne(command.getName(), param); } } else { throw new BindingException("Unknown execution method for: " + command.getName()); } if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) { throw new BindingException("Mapper method '" + command.getName() + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ")."); } return result; }

    SqlSessionTemplate 执行了创建sqlsession,openSqlsession,执行sql,closeSqlsession

     

  • 相关阅读:
    HTTP以及TCP协议
    分布式理论
    JAVA基础面试题
    JAVA基础面试题
    vue 中百度富文本初始化内容加载失败(编辑操作某列数据时,富文本中内容偶尔会为空)
    CodeMirror的使用方法
    JSON格式化,JSON.stringify()的用法
    promise与await的用法
    服务器端node.js
    数组扁平化
  • 原文地址:https://www.cnblogs.com/fanBlog/p/9525002.html
Copyright © 2011-2022 走看看