mybatis工作原理(精华)

1.创建SqlSessionFactoryBuilder对象,调用build方法读取并解析配置文件,返回SqlSessionFactory对象。方法中还会调用重载方法parse(),parse()方法又会去调用parseConfigation()方法,在该方法中可以看到读取了各个标签内容并封装到Configuration对象的的属性中并返回。该对象中有两个重要的Map,mappedStatementsMap:key:是全限定名+方法名,value:sql语句;还有一个map是用来存储代理类对象的,key:接口的字节码对象 value:此接口对应的MapperProxyFactory对象
所以解析xml就是给Configuration对象的属性复制的
2.由SqlSessionFactory调用opensession()方法创建SqlSession 对象,SqlSession对象是MyBatis中用于和数据库交互的顶层类,主要有两个重要属性,Configation,Executor。
3.创建完sqlsession对象后,调用SqlSession中的api,根据传入的全限定名+方法名从configuration对象的mappedStatementsMap集合中取出MappedStatement对象,一个MappedStatement对象对应着一条sql语句,
4.然后调用executor的query()方法或者update()方法,去执行sql,该方法中还有二级缓存的实现过程。
在这里插入图片描述

//在创建XMLConfigBuilder时,它的构造方法中解析器XPathParser已经读取了配置文件
//3. 进入XMLConfigBuilder 中的 parse()方法。
public Configuration parse() {
    
    
    if (parsed) {
    
    
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    //parser是XPathParser解析器对象,读取节点内数据,<configuration>是MyBatis配置文件中的顶层标签
    parseConfiguration(parser.evalNode("/configuration"));
    //最后返回的是Configuration 对象
    return configuration;
}

//4. 进入parseConfiguration方法
//此方法中读取了各个标签内容并封装到Configuration中的属性中。
private void parseConfiguration(XNode root) {
    
    
    try {
    
    
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      loadCustomVfs(settings);
      loadCustomLogImpl(settings);
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      settingsElement(settings);
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
    
    
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
}


缓存

一级缓存:sqlsession级别,是默认开启的,同一条sql语句第二次查询将直接从缓存中取,不会执行sql语句,当两次查询中做了cud操作的话,缓存将被清除,第二次也会执行sql语句
二级缓存:namespace级别,多个SqlSession之间可以共享缓存,会使用CachingExecutor装饰Executor,进入一级缓存的查询流程前,会先在CachingExecutor进行二级缓存的查询。所以数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

猜你喜欢

转载自blog.csdn.net/JavaSupeMan/article/details/117290660