mybatis学习笔记(上)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Mybatis与spring集成时,在spring.xml中会配置两个重要的类,SqlSessionFactoryBean与MapperScannerConfigure。用于完成mybatis的加载与配置。

Mybatis与spring集成时,在spring.xml中会配置两个重要的类,SqlSessionFactoryBean与MapperScannerConfigure。用于完成mybatis的加载与配置。

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 自动扫描mapping.xml文件 -->
        <property name="mapperLocations" value="classpath:com/rsms/iot/mapper/*.xml"/>
        <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
</bean>
 <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.rsms.iot.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>


一、Mybatis核心类图


核心类是SqlSessionFactory和SqlSession


image.png

mybatis类图.png


二、Mybatis加载过程


Mybatis自带的加载过程,集成到spring之后,加载过程会有一些变化,主要是bean要提交给spring容器来管理


image.png

mybatis加载过程.png


三、SqlSessionFactoryBean介绍


spring配置mybatis的加载入口

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations" value="classpath:com/rsms/iot/mapper/*.xml"/>
    <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
</bean>


configLocation指定mybatis的全局配置位置


mapperLocations指定隐射文件的配置位置


SqlSessionFactoryBean实现接口InitializingBean,在bean加载完成后执行

afterPropertiesSet完成SqlSessionFactory的创建。SqlSessionFactoryBean重新实现了mybatis原生的SqlSessionFactory的构建过程。在buildSqlSessionFactory()方法中通过XMLConfigBuilder完成对全局配置文件的解析,并构造Configuration对象。Configuration对象是全局唯一的提供了mybatis的所有配置项。


然后解析mapper文件

if (!isEmpty(this.mapperLocations)) {
      for (Resource mapperLocation : this.mapperLocations) {
        if (mapperLocation == null) {
          continue;
        }
        try {
          XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
              configuration, mapperLocation.toString(), configuration.getSqlFragments());
          xmlMapperBuilder.parse();
        } catch (Exception e) {
          throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
        } finally {
          ErrorContext.instance().reset();
        }
        if (LOGGER.isDebugEnabled()) {
          LOGGER.debug("Parsed mapper file: '" + mapperLocation + "'");
        }
      }
    } else {
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Property 'mapperLocations' was not specified or no matching resources found");
      }
}


mapper文件是通过XMLMapperBuilder解析

public void parse() {
    if (!configuration.isResourceLoaded(resource)) {
      configurationElement(parser.evalNode("/mapper"));
      configuration.addLoadedResource(resource);
      bindMapperForNamespace();
    }
    parsePendingResultMaps();
    parsePendingChacheRefs();
    parsePendingStatements();
}
private void configurationElement(XNode context) {
    try {
      String namespace = context.getStringAttribute("namespace");
      if (namespace == null || namespace.equals("")) {
        throw new BuilderException("Mapper's namespace cannot be empty");
      }
      builderAssistant.setCurrentNamespace(namespace);
      cacheRefElement(context.evalNode("cache-ref"));
      cacheElement(context.evalNode("cache"));
      parameterMapElement(context.evalNodes("/mapper/parameterMap"));
      resultMapElements(context.evalNodes("/mapper/resultMap"));
      sqlElement(context.evalNodes("/mapper/sql"));
      //过滤出所有的curd sql片段
      buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);
    }
}


循环解析所有mapper.xml文件,过滤出curd sql片段,构造MappedStatment(一个sql是一个MappedStatment)存放到Configuration对象的mappedStatements中,mappedStatements是StrictMap,继承hashmap,在存放的时候会存放两份,一份是id+namespace作为key值,一份是id作为key值。value值就是MappedStatment对象。

相关文章
|
5月前
|
SQL Java 关系型数据库
MyBatisPlus学习笔记(SpringBoot版)
MyBatisPlus学习笔记(SpringBoot版)
494 0
|
XML Java 数据库连接
java202304java学习笔记第六十五天-ssm-声明式控制-基于xml的声明式配置-mybatis的概述2
java202304java学习笔记第六十五天-ssm-声明式控制-基于xml的声明式配置-mybatis的概述2
50 0
java202304java学习笔记第六十六天-ssm-mybatis-接口代理方法实现
java202304java学习笔记第六十六天-ssm-mybatis-接口代理方法实现
41 0
|
SQL Java 关系型数据库
|
SQL Java 关系型数据库
java202304java学习笔记第六十六天-ssm-mybatis的dao层实现1
java202304java学习笔记第六十六天-ssm-mybatis的dao层实现1
34 0
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-foreach之2
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-foreach之2
53 0
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-if之1
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-if之1
34 0