0
点赞
收藏
分享

微信扫一扫

SpringBoot整合Mybatis的核心原理

杰森wang 2023-02-10 阅读 149

0. 前言:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud?characterEncoding=utf8&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
    username: root
    password: 123456
    
mybatis:
  # mybatis-config.xml 配置文件的路径 与 configuration 不可一起设置
  #config-location: classpath:mapper/mybatis-config.xml
  # sql映射文件的位置
  mapper-locations: classpath:mapper/*.xml
  # 开启驼峰命名转化
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  # 开启别名
  type-aliases-package: com.example.demo.easy.domain

1. 自动配置类MybatisAutoConfiguration:

1.1. SqlSessionFactory的生成:

  @Bean
  @ConditionalOnMissingBean
  public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setDataSource(dataSource);
    factory.setVfs(SpringBootVFS.class);
    if 	(StringUtils.hasText(this.properties.getConfigLocation())) {
      factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
    }
  
 	// ... ... 省略一些赋值,详细可看源码
    if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
      factory.setMapperLocations(this.properties.resolveMapperLocations());
   }   
    return factory.getObject();
  }

在这里插入图片描述

 protected SqlSessionFactory buildSqlSessionFactory() throws Exception {

    final Configuration targetConfiguration;

    XMLConfigBuilder xmlConfigBuilder = null;
    if (this.configuration != null) {
 		... ...
    } else if (this.configLocation != null) {
      xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
      targetConfiguration = xmlConfigBuilder.getConfiguration();
    } else {
 		... ...
    }
	// ... ... yml的配置项赋值targetConfiguration
    if (hasLength(this.typeAliasesPackage)) {
      scanClasses(this.typeAliasesPackage, this.typeAliasesSuperType).stream()
          .filter(clazz -> !clazz.isAnonymousClass()).filter(clazz -> !clazz.isInterface())
          .filter(clazz -> !clazz.isMemberClass()).forEach(targetConfiguration.getTypeAliasRegistry()::registerAlias);
    }
    
	... ...

    if (xmlConfigBuilder != null) {
      try {
      	// 解析mybatis-config.xml配置项并会覆盖yml的配置
        xmlConfigBuilder.parse();
        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.mapperLocations != null) {
      	  ... ...
          try {
          	// mapper.xml会被解析封装成MappedStatement对象(用于存储要映射的SQL语句的id、参数等信息)
            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
                targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());
            xmlMapperBuilder.parse();
          } 
          ... ...
        }
      }
    } else {
      LOGGER.debug(() -> "Property 'mapperLocations' was not specified.");
    }
	// 创建DefaultSqlSessionFactory
    return this.sqlSessionFactoryBuilder.build(targetConfiguration);
  }

1.2. Mapper的扫描和代理生成:

  @org.springframework.context.annotation.Configuration
  @Import(AutoConfiguredMapperScannerRegistrar.class)
  @ConditionalOnMissingBean({ MapperFactoryBean.class, MapperScannerConfigurer.class })
  public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {

    @Override
    public void afterPropertiesSet() {
      logger.debug(
          "Not found configuration for registering mapper bean using @MapperScan, MapperFactoryBean and MapperScannerConfigurer.");
    }

  }

在这里插入图片描述

1.2.1. MapperScannerConfigurer

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1.2.2. MapperFactoryBean

在这里插入图片描述

1.2.3. getMapper生成代理对象

在这里插入图片描述
在这里插入图片描述

2. 小结:

举报

相关推荐

0 条评论