<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      mybatis筆記3 一些原理的理解

      1,mybatis流程跟蹤,原理理解

        基本思路: 從SqlSessionFactory的初始化出發,觀察資源的準備和環境的準備,以及實現持久層的一些過程;

       

      進入SqlSessionFactoryBean類,發現先執行的是

      image

      然后是:

      image

      在初始化類之后,做的準備工作如下:

      public void afterPropertiesSet() throws Exception {
          notNull(dataSource, "Property 'dataSource' is required");//1,檢查spring準備的datasource是否ok
          notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");//2,檢查空構造方法的sqlSessionFactoryBuilder是否準備好

          this.sqlSessionFactory = buildSqlSessionFactory();//3,利用配置的屬性,構造sqlSessionFactory
        }

      構造細節如下:方法有點長,注意注釋這個是流程,之后我畫一個圖來加深理解;

      protected SqlSessionFactory buildSqlSessionFactory() throws IOException {

         Configuration configuration;

         XMLConfigBuilder xmlConfigBuilder = null;
         if (this.configLocation != null) {//1,檢查是否有配置configLocation,即mybatis的整體配置文件,非mapper文件,如果有加載進去,沒有,構造一個空的
           xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
           configuration = xmlConfigBuilder.getConfiguration();
         } else {
           if (logger.isDebugEnabled()) {
             logger.debug("Property 'configLocation' not specified, using default MyBatis Configuration");
           }
           configuration = new Configuration();
           configuration.setVariables(this.configurationProperties);
         }

         if (this.objectFactory != null) {//2,檢查對象工廠,如果有設置進去,沒有留空
           configuration.setObjectFactory(this.objectFactory);
         }

         if (this.objectWrapperFactory != null) {//3,檢查對象裝飾工廠,如果有設置進去,沒有留空

           configuration.setObjectWrapperFactory(this.objectWrapperFactory);
         }

         if (hasLength(this.typeAliasesPackage)) {//4,檢查包的簡稱,如果有注冊進去
           String[] typeAliasPackageArray = tokenizeToStringArray(this.typeAliasesPackage,
               ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
           for (String packageToScan : typeAliasPackageArray) {
             configuration.getTypeAliasRegistry().registerAliases(packageToScan,
                     typeAliasesSuperType == null ? Object.class : typeAliasesSuperType);
             if (logger.isDebugEnabled()) {
               logger.debug("Scanned package: '" + packageToScan + "' for aliases");
             }
           }
         }

         if (!isEmpty(this.typeAliases)) {//5,檢查類的簡稱,如果有注冊進去
           for (Class<?> typeAlias : this.typeAliases) {
             configuration.getTypeAliasRegistry().registerAlias(typeAlias);
             if (logger.isDebugEnabled()) {
               logger.debug("Registered type alias: '" + typeAlias + "'");
             }
           }
         }

         if (!isEmpty(this.plugins)) {//6,檢查插件,如果有注冊進去
           for (Interceptor plugin : this.plugins) {
             configuration.addInterceptor(plugin);
             if (logger.isDebugEnabled()) {
               logger.debug("Registered plugin: '" + plugin + "'");
             }
           }
         }

         if (hasLength(this.typeHandlersPackage)) {//7,檢查類型轉換類包,如果有注冊進去
           String[] typeHandlersPackageArray = tokenizeToStringArray(this.typeHandlersPackage,
               ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
           for (String packageToScan : typeHandlersPackageArray) {
             configuration.getTypeHandlerRegistry().register(packageToScan);
             if (logger.isDebugEnabled()) {
               logger.debug("Scanned package: '" + packageToScan + "' for type handlers");
             }
           }
         }

         if (!isEmpty(this.typeHandlers)) {//8,檢查類型轉換類,如果有注冊進去
           for (TypeHandler<?> typeHandler : this.typeHandlers) {
             configuration.getTypeHandlerRegistry().register(typeHandler);
             if (logger.isDebugEnabled()) {
               logger.debug("Registered type handler: '" + typeHandler + "'");
             }
           }
         }

         if (xmlConfigBuilder != null) {//9,檢查是否有xml的構造器,如果有,直接使用構造器構造
           try {
             xmlConfigBuilder.parse();

             if (logger.isDebugEnabled()) {
               logger.debug("Parsed configuration file: '" + this.configLocation + "'");
             }
           } catch (Exception ex) {
             throw new NestedIOException("Failed to parse config resource: " + this.configLocation, ex);
           } finally {
             ErrorContext.instance().reset();
           }
         }

         if (this.transactionFactory == null) {//10,檢查事物工廠,如果沒有,構造一個spring管理的事物工廠
           this.transactionFactory = new SpringManagedTransactionFactory();
         }

      //11,構造環境變量

         Environment environment = new Environment(this.environment, this.transactionFactory, this.dataSource);
         configuration.setEnvironment(environment);

         if (this.databaseIdProvider != null) {
           try {//12,檢查是否配置了db id,如果有,設置到配置的類中
             configuration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));
           } catch (SQLException e) {
             throw new NestedIOException("Failed getting a databaseId", e);
           }
         }

         if (!isEmpty(this.mapperLocations)) {//13,把配置的mapper弄進來總配置文件里
           for (Resource mapperLocation : this.mapperLocations) {
             if (mapperLocation == null) {
               continue;
             }

             try {
               XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
                   configuration, mapperLocation.toString(), configuration.getSqlFragments());
               xmlMapperBuilder.parse();
             } catch (Exception e) {
               throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
             } finally {
               ErrorContext.instance().reset();
             }

             if (logger.isDebugEnabled()) {
               logger.debug("Parsed mapper file: '" + mapperLocation + "'");
             }
           }
         } else {
           if (logger.isDebugEnabled()) {
             logger.debug("Property 'mapperLocations' was not specified or no matching resources found");
           }
         }

         return this.sqlSessionFactoryBuilder.build(configuration);//14,最后通過得到的配置類來構造一個sqlsessionFactory工廠
      }

       

      設置好屬性之后,執行

      image

      得到factory構造的bean,即sqlSessionFactory,

      最后容器啟動成功的事件監控

      public void onApplicationEvent(ApplicationEvent event) {
         if (failFast && event instanceof ContextRefreshedEvent) {
           // fail-fast -> check all statements are completed
           this.sqlSessionFactory.getConfiguration().getMappedStatementNames();
         }
      }

      以上是資源的準備,下面來一次增刪改查的跟蹤,觀察內部的工作原理;

       

      查詢單條記錄的過程:

       

      public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
        try {
          MappedStatement ms = configuration.getMappedStatement(statement);//1,通過轉換,得到存儲的mapperedStatement
          List<E> result = executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);//2,轉換成jdbc代碼執行
          return result;
        } catch (Exception e) {
          throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
        } finally {
          ErrorContext.instance().reset();
        }
      }

      內部就像是一臺精密的儀器,去除了大量的模版jdbc代碼;

      posted @ 2014-03-05 14:16  李福春  閱讀(14851)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 疯狂做受XXXX高潮国产| 久久不见久久见免费视频| 国产欧美精品aaaaaa片| 国偷自产一区二区三区在线视频| 亚洲av成人精品日韩一区| gogo无码大胆啪啪艺术| 欧美性大战xxxxx久久久| 激情综合五月| 中文字幕第一页亚洲精品| 亚洲国产精品久久久天堂麻豆宅男 | 国产办公室秘书无码精品99| 无码专区 人妻系列 在线| 亚洲乱码一卡二卡卡3卡4卡| 国产老熟女伦老熟妇露脸| 亚洲AV无码不卡在线播放| 国产乱码精品一区二区三上 | 国产电影一区二区三区| 中文字幕亚洲人妻一区| 国产超碰无码最新上传| 亚洲日韩精品无码一区二区三区| 欧美国产日韩久久mv| 欧美饥渴熟妇高潮喷水| 亚洲熟女精品一区二区| 乱人伦中文字幕成人网站在线| 欧美在线精品一区二区三区| 久久精品不卡一区二区| 日本亚洲一区二区精品久久| 免费超爽大片黄| 久久日韩精品一区二区五区| 在线看无码的免费网站| 午夜国产精品福利一二| 久久久久久亚洲精品a片成人| 国产不卡一区二区精品| 精品亚洲一区二区三区四区 | 无锡市| 少妇人妻偷人精品免费| 国产精品中文一区二区| 爆乳女仆高潮在线观看| 日韩精品无码一区二区视频| 精品人妻av区乱码| 一区二区三区久久精品国产|