mybatis源码分析-----sqlSessionFactory创建

Posted 千寻

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis源码分析-----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则是建造出来的产品

 

 

  •   总结

 

以上是关于mybatis源码分析-----sqlSessionFactory创建的主要内容,如果未能解决你的问题,请参考以下文章

mybatis源码阅读mybatis与spring整合原理

Mybatis中SqlSessionFactory和SqlSession学习和原理

[mybatis]缓存_一级缓存

MyBatis源码分析环境准备

Mybatis源码分析

MyBatis工厂工具类 MyBatisUtils