This is the 9th day of my participation in the August Wen Challenge.More challenges in August

Mybatis a popular interview question: Mybatis interface is how to execute SQL?

Many online are based on pure Mybatis, I here is the main starting point in our common SpringBoot project, how to let us only through the interface can go to the corresponding SQL.

Spring integrates a lot of third-party starter auto-assembly for fast integration, and Mybatis is no exception. The entrance of our analysis is based on mybatis- Spring-boot-Starter as an example. Here, the latest dependency version 2.1.4 is used for analysis.

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>
Copy the code

What’s in this bag?

Starter is an empty package that specifies some dependencies (this is a specification of spring’s official starter, and the auto-configuration is all inmybatis-spring-boot-autoconfigureInside).

Three important packages have been introduced:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-autoconfigure</artifactId>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
  </dependency>
</dependencies>
Copy the code

The functions of these three packages are:

  • Mybatis -spring-boot-starter: is only responsible for integrating dependencies, similar to parent.
  • Mybatis -spring-boot-autoconfigure: is only responsible for automatic configuration.
  • Mybatis – Spring: Responsible for the core part of spring and Mybatis combination, which is the focus of this part.

Let’s start with autoconfiguration (mybatis-spring-boot-autoconfigure-2.1.4.jar), where the key classes are selected.

  1. Look at the spring. Factories:

    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
    org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
    Copy the code
  2. It can be seen that the key is MybatisAutoConfiguration, which realizes the automatic configuration of MyBatis, and the specific configuration options are actually the content of MybatisProperties.

  3. Let’s look at this code:

    @Configuration
    @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
    @ConditionalOnSingleCandidate(DataSource.class)
    @EnableConfigurationProperties({MybatisProperties.class})
    @AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
    public class MybatisAutoConfiguration implements InitializingBean {
    
        private finalMybatisProperties properties; .@Bean
        @ConditionalOnMissingBean
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
          	SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
            // add the properties and datasource data to the SqlSessionFactoryBean object.
            return factory.getObject();
        }
    
        @Bean
        @ConditionalOnMissingBean
        public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {... }@Configuration
        @Import({MybatisAutoConfiguration.AutoConfiguredMapperScannerRegistrar.class})
        @ConditionalOnMissingBean({MapperFactoryBean.class, MapperScannerConfigurer.class})
        public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {
            public MapperScannerRegistrarNotFoundConfiguration(a) {}public void afterPropertiesSet(a) {
                MybatisAutoConfiguration.logger.debug("Not found configuration for registering mapper bean using @MapperScan, MapperFactoryBean and MapperScannerConfigurer."); }}}Copy the code
    • And you can see it’s created hereSqlSessionFactoryandSqlSessionTemplateThe two coresbean.And buildSqlSessionFactoryThe core is to rely onSqlSessionFactoryBeanOf this class, and this class is inMybatis - spring - 2.0.6. JarUnder the bag.
  4. We know that in the pure Spring and Mybatis scenario, we get Mapper to use like this:

    Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    XXMapper mapper = sqlSession.getMapper(XXMapper.class);
    Copy the code

    However, the configuration of this part of mybatis-config.xml is now up to Spring to automate. SqlSessionFactory is built by SqlSessionFactoryBuilder, so springBoot is no exception. The only difference is: The above method is to use SqlSessionFactory. Build (Reader Reader) method, and springboot automatic Configuration is to use the SqlSessionFactoryBuilder is. Build (Configuration). The Configuration object is created by ourselves.

    SqlSessionFactoryBuilder = SqlSessionFactoryBuilder = SqlSessionFactory
    private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();    
    private SqlSessionFactory sqlSessionFactory;
    /** * only core methods are selected */
    @Override
    public SqlSessionFactory getObject(a) throws Exception {
        if (this.sqlSessionFactory == null) {
            afterPropertiesSet();
        }
        return this.sqlSessionFactory;
    }
    
    @Override
    public void afterPropertiesSet(a) throws Exception {...this.sqlSessionFactory = buildSqlSessionFactory();
    }
    
    protected SqlSessionFactory buildSqlSessionFactory(a) throws Exception {
        final Configuration targetConfiguration;
        XMLConfigBuilder xmlConfigBuilder = null;
        / / build configuration
        if (this.configuration ! =null) {
            targetConfiguration = this.configuration;
            if (hasLength(this.typeAliasesPackage)) { }
            if(! isEmpty(this.typeAliases)) { }
            if(! isEmpty(this.plugins)) { }
            if (hasLength(this.typeHandlersPackage)) { }
            if(! isEmpty(this.typeHandlers)) { }
            targetConfiguration.setDefaultEnumTypeHandler(defaultEnumTypeHandler);
            Optional.ofNullable(this.cache).ifPresent(targetConfiguration::addCache);
            if (this.mapperLocations ! =null) {}return this.sqlSessionFactoryBuilder.build(targetConfiguration); }}Copy the code

SqlSessionFactory = Mybatis = SqlSessionFactory = SqlSessionFactory = SqlSessionFactory = SqlSessionFactory = SqlSessionFactory = SqlSessionFactory = SqlSessionFactory = SqlSessionFactory

After the automatic configuration is complete, the container will inject the SqlSession instance bean (the default implementation of the SqlSessionTemplate) and the contents of our mapper. XML will be parsed and saved into a map of mappedStatements and mapper. XML

<mapper namespace="work.lollipops.demo.mybatis.mapper.TB1Mapper">
Copy the code

Resolve the configuration into mapperRegistry’s knownMappers (also a map).

These two things are very useful, all method execution of MyBatis will be around these two things.