• mybatis源码分析(1)-----sqlSessionFactory创建


    1. 首先了解一下mybatis,包含核心jar ,以及spring相关jar.

    <!-- Mybatis相关组件 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.2.3</version>
    </dependency>
    • 系列的文章也是mybatis 3.3.0和mybatis-spring1.2.3分析
    • mybatis jar包中只要包含mybaits的核心业务sqlsession,sqlsessionFactory,configuration
    • mybatis-spring 包中只要是和spring的相关集成,sqlSessionFactoryBean、transaction

    2. 加载mybatis

    本文以spring中加载mybatis为参考,由一下代码加载mybatis

    <!-- 配置集成Mybatis -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:/config/SQLMapConfig.xml" />
        <property name="mapperLocations"
            value="classpath*:com/chihiro/*/**/infra/mybatis/*Mapper.xml" />
    </bean>
    • sqlSessionFactory接口(mybatis包核心接口)

      a、接口中有如下方法。子类中含有所有方法的实现

    public interface SqlSessionFactory {
      SqlSession openSession();
      SqlSession openSession(boolean autoCommit);
      SqlSession openSession(Connection connection);
      SqlSession openSession(TransactionIsolationLevel level);
      SqlSession openSession(ExecutorType execType);
      SqlSession openSession(ExecutorType execType, boolean autoCommit);
      SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
      SqlSession openSession(ExecutorType execType, Connection connection);
      Configuration getConfiguration();
    }

      b、接口的实现类,由sqlSessionFactoryBean产生的是默认的SqlSessionFactory(DefaultSqlSessionFactory)

      

    •  sqlSessionFactoryBean(mybatis-spring包下面的创建工厂的Bean,由spring 加载初始化)

      a、从上述mybais的加载,可以看到,构造sqlSessionFactoryBean之后给了默认的属性值,dataSource,configLocation,mapper

    public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
    
      private static final Log LOGGER = LogFactory.getLog(SqlSessionFactoryBean.class);
    
      private Resource configLocation;
    
      private Resource[] mapperLocations;
    
      private DataSource dataSource;
    
      //SqlSessionFactory 构造的协助类
      private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    
      private SqlSessionFactory sqlSessionFactory;
    
      //创建sqlSessionFactory的方法体
      protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
          Configuration configuration;
          XMLConfigBuilder xmlConfigBuilder = null;
          if (this.configLocation != null) {
        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);
        }
        ...
        return this.sqlSessionFactoryBuilder.build(configuration);
      }ss
    
      @Override
      public void afterPropertiesSet() throws Exception {
        notNull(dataSource, "Property 'dataSource' is required");
        notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
        //调用方法创建sqlSessionFactory
        this.sqlSessionFactory = buildSqlSessionFactory();
      }
    
      @Override
      public void onApplicationEvent(ApplicationEvent event) {
        if (failFast && event instanceof ContextRefreshedEvent) {
          // fail-fast -> check all statements are completed
          this.sqlSessionFactory.getConfiguration().getMappedStatementNames();
        }
      }
    
    }
    1. 实现3个相关接口的作用

        FactoryBean接口:实现了该接口的类,在调用getBean(获取bean对象)的时候会返回该工厂返回的实例对象,也就是再调一次getObject方法返回工厂的实例。

        InitializingBean接口:实现了这个接口,那么当bean初始化的时候,spring就会调用该接口的实现类的afterPropertiesSet方法,去实现当spring初始化该Bean的时候所需要的逻辑。

        ApplicationListener接口:实现了该接口,如果注册了该监听的话,那么就可以了监听到Spring的一些事件,然后做相应的处理

         2.在bean初始化之后,可以看见,回调方法afterPropertiesSet,在里面构造configuration对象。以及产生sqlSession

        Configuration类:可以发现配置中读取configuration。(核心配置,关联mybatis整个生命周期)

          xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
          configuration = xmlConfigBuilder.getConfiguration();

        3.由sqlSessionFactoryBuild 构造sqlSessionFactory

    public class SqlSessionFactoryBuilder {
        
      public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
      }
    
    }

    4. 建设者模式

      生产sqlSessionFacoty 使用了建设者模式(Builder)。其构造过程主要注入了Configuration的实例对象,sqlSessionFactoryBuilder 扮演具体的建造者,configuration类主要负责建造细节的工作,sqlSessionFactory则是建造出来的产品

    •   总结

  • 相关阅读:
    【题解】警位安排( 树形 DP)
    【题解】任务分配
    Leo 搭积木
    受牛仰慕的牛
    zy 送画
    [NOIP2010] 乌龟棋
    [WikiOi 1214] 线段覆盖
    【拓扑习题】课程安排问题
    [WikiOI "天梯"1281] Xn数列
    [百度之星2014资格赛] Disk Schedule 报告
  • 原文地址:https://www.cnblogs.com/chihirotan/p/6591425.html
Copyright © 2020-2023  润新知