• mybatis


    一. MybatisProperties 

    在使用 mybatis 时, 还需要对mapper进行配置:

    mybatis:
        mapper-locations: classpath:mapper/**Mapper.xml

    这些配置其实是映射到 mybatis-spring-boot-autoconfigure 包下的  MybatisProperties 文件中的.

    @ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)
    public class MybatisProperties {
    
      public static final String MYBATIS_PREFIX = "mybatis";
    
      /**
       * Location of MyBatis xml config file.
       */
      private String configLocation;
    
      /**
       * Locations of MyBatis mapper files.
       */
      private String[] mapperLocations;
    
      /**
       * Packages to search type aliases. (Package delimiters are ",; 	
    ")
       */
      private String typeAliasesPackage;
    
      /**
       * Packages to search for type handlers. (Package delimiters are ",; 	
    ")
       */
      private String typeHandlersPackage;
    
      /**
       * Indicates whether perform presence check of the MyBatis xml config file.
       */
      private boolean checkConfigLocation = false;
    
      /**
       * Execution mode for {@link org.mybatis.spring.SqlSessionTemplate}.
       */
      private ExecutorType executorType;
    
      /**
       * Externalized properties for MyBatis configuration.
       */
      private Properties configurationProperties;
    
      /**
       * A Configuration object for customize default settings. If {@link #configLocation}
       * is specified, this property is not used.
       */
      @NestedConfigurationProperty
      private Configuration configuration;
    ......
    }

    二. MybatisAutoConfiguration 

    MybatisAutoConfiguration 是 mybatis-spring-boot-autoconfigure 中的一个配置类.

    在这个配置类中, 主要加入了两个组件: SqlSessionFactory 和 SqlSessionTemplate

    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()));
        }
        Configuration configuration = this.properties.getConfiguration();
        if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {
          configuration = new Configuration();
        }
        if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {
          for (ConfigurationCustomizer customizer : this.configurationCustomizers) {
            customizer.customize(configuration);
          }
        }
        factory.setConfiguration(configuration);
        if (this.properties.getConfigurationProperties() != null) {
          factory.setConfigurationProperties(this.properties.getConfigurationProperties());
        }
        if (!ObjectUtils.isEmpty(this.interceptors)) {
          factory.setPlugins(this.interceptors);
        }
        if (this.databaseIdProvider != null) {
          factory.setDatabaseIdProvider(this.databaseIdProvider);
        }
        if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
          factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
        }
        if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
          factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
        }
        if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
          factory.setMapperLocations(this.properties.resolveMapperLocations());
        }
    
        return factory.getObject();
      }

    (从名字可以看出来, SqlSessionFactory 是 SqlSession的一个工厂类. SqlSession 这个类很重要, 里面定义了 数据库的一套增删改查操作的规范.)

    MybatisProperties 中的配置会在这个方法中进行解析.

    1. 创建了 Configuration 配置类(后面会用到, 这个类也很重要)的实例

    2. 通过 factory.getObject() 方法创建了 SqlSessionFactory 类的实例

    创建的过程中, 又调用了 protected SqlSessionFactory buildSqlSessionFactory() 方法进行创建, 创建过程比较多, 留给后面在解析.

    2. SqlSessionTemplate 

      @Bean
      @ConditionalOnMissingBean
      public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        ExecutorType executorType = this.properties.getExecutorType();
        if (executorType != null) {
          return new SqlSessionTemplate(sqlSessionFactory, executorType);
        } else {
          return new SqlSessionTemplate(sqlSessionFactory);
        }
      }

    SqlSessionTemplate 这个类 实现了 SqlSession 接口,  也就是说, 他也有一套 数据库的 增删改查的方法. 先看一下构造过程:

      public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
      }
    
     |
     |
    |/
    
      public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {
        this(sqlSessionFactory, executorType,
            new MyBatisExceptionTranslator(
                sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true));
      }
    
     |
     |
    |/
    
      public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
          PersistenceExceptionTranslator exceptionTranslator) {
    
        notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
        notNull(executorType, "Property 'executorType' is required");
    
        this.sqlSessionFactory = sqlSessionFactory;
        this.executorType = executorType;
        this.exceptionTranslator = exceptionTranslator;
        this.sqlSessionProxy = (SqlSession) newProxyInstance(
            SqlSessionFactory.class.getClassLoader(),
            new Class[] { SqlSession.class },
            new SqlSessionInterceptor());
      }

    这里初始化了一个很重要的属性:  sqlSessionProxy. 

    sqlSessionProxy 是为 SqlSession 创建了一个代理类, 且代理方法为:  SqlSessionInterceptor

    看一个 实现了 SqlSession 接口中的  selectOne 方法:

      @Override
      public <T> T selectOne(String statement, Object parameter) {
        return this.sqlSessionProxy.<T> selectOne(statement, parameter);
      }

    可以看到, 在调用 selectOne 方法的时候, 其实就是调用了 SqlSessionInterceptor 的 invoke 方法.

  • 相关阅读:
    position之属性
    Grid网格布局
    position 属性指定了元素的定位类型
    注册表单
    简单页面
    自我介绍
    正则表达式
    Dom和Bom
    颜色和单位
    伪类和伪元素的区别
  • 原文地址:https://www.cnblogs.com/elvinle/p/12297104.html
Copyright © 2020-2023  润新知