小胡的博客

  • 首页
  • 文章归档
  • 默认分类
  • 关于页面

  • 搜索

002-mybatisXml解析

发表于 2020-04-09 | 分类于 mybaits | 0 | 阅读次数 16926

整个XML解析概览

# builder初始化
>org.apache.ibatis.session.Configuration#Configuration() 初始化内置别名

>org.apache.ibatis.session.SqlSessionFactoryBuilder#build(java.io.InputStream, java.lang.String, java.util.Properties)
 >org.apache.ibatis.builder.xml.XMLConfigBuilder#parse
  >org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration  解析配置文件
   >org.apache.ibatis.builder.xml.XMLConfigBuilder#propertiesElement 解析 properties 标签,定义key、value配置
  >org.apache.ibatis.builder.xml.XMLConfigBuilder#mapperElement 安装mapper路径配置进行解析,构建 XMLMapperBuilder mapperParser,每一个mapper文件对应一个XMLMapperBuilder
   >org.apache.ibatis.builder.xml.XMLMapperBuilder#parse  
    >org.apache.ibatis.builder.xml.XMLMapperBuilder#configurationElement  开始解析单个mapper
	 >org.apache.ibatis.builder.xml.XMLMapperBuilder#cacheElement cache配置,如果自定义缓存需要实现org.apache.ibatis.cache.Cache接口
	 >org.apache.ibatis.builder.xml.XMLMapperBuilder#resultMapElement(org.apache.ibatis.parsing.XNode, java.util.List<org.apache.ibatis.mapping.ResultMapping>, java.lang.Class<?>)
		解析resultMap,最终构建成ResultMapResolver,里面每一行result封装成ResultMapping
	 >org.apache.ibatis.builder.xml.XMLMapperBuilder#sqlElement(java.util.List<org.apache.ibatis.parsing.XNode>, java.lang.String)  Map<String, XNode> sqlFragments; 解析sql标签
	  >org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode "select|insert|update|delete" 标签解析方法
       >org.apache.ibatis.session.Configuration#getLanguageDriver  获取LanguageDriver, 默认为XMLLanguageDriver
       > org.apache.ibatis.scripting.xmltags.XMLScriptBuilder#parseScriptNode 构建SqlSource,  如果是非动态sql,也就是未使用<if>等标签,则会构建则会构建RawSqlSource,否则构建为DynamicSqlSource,区别在于RawSqlSource会对#进行预处理,更快
       > org.apache.ibatis.builder.MapperBuilderAssistant#addMappedStatement(java.lang.String, org.apache.ibatis.mapping.SqlSource, org.apache.ibatis.mapping.StatementType, org.apache.ibatis.mapping.SqlCommandType, java.lang.Integer, java.lang.Integer, java.lang.String, java.lang.Class<?>, java.lang.String, java.lang.Class<?>, org.apache.ibatis.mapping.ResultSetType, boolean, boolean, boolean, org.apache.ibatis.executor.keygen.KeyGenerator, java.lang.String, java.lang.String, java.lang.String, org.apache.ibatis.scripting.LanguageDriver, java.lang.String)
           构建 MappedStatement,构建完成后 put到org.apache.ibatis.session.Configuration#mappedStatements中
   >org.apache.ibatis.builder.xml.XMLMapperBuilder#bindMapperForNamespace  绑定mapper接口
    > org.apache.ibatis.binding.MapperRegistry#addMapper  解析mapper接口,解析完成后会放入到knownMappers的map中,key为class type, value为MapperProxyFactory
    > org.apache.ibatis.builder.annotation.MapperAnnotationBuilder#parse 注解解析

parse

  public Configuration parse() {
    // 防止二次加载
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    // /configuration 为xml配置的 根节点。
    // parseConfiguration 加载自己所需的配置
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

parsed是一个全局变量,默认为false。
parseConfiguration是具体的解析方法

private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      // 自定义配置属性  这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。
      propertiesElement(root.evalNode("properties"));
      //这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项的意图、默认值等。
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      // vfsImpl ?? 不太清楚撒玩意      VFS含义是虚拟文件系统;主要是通过程序能够方便读取本地文件系统、FTP文件系统等系统中的文件资源。
      // 自定义VFS实现,VFS是Mybatis 虚拟的一层文件系统,不用在意底层,可以拓展支持其他实现支持资源访问。
      loadCustomVfs(settings);
      // 	指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
      loadCustomLogImpl(settings);
      // 类型别名是为 Java 类型设置一个短的名字。 它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。
      typeAliasesElement(root.evalNode("typeAliases"));
      // 插件。MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。
      pluginElement(root.evalNode("plugins"));
//      对象工厂(objectFactory)
//      MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。
//      默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。
//      如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。
      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"));
      // 数据库厂商标识,如果官方不支持的数据库 通过这个来自己拓展????
      // todo  待考证
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      // 类型处理器(typeHandlers)
      typeHandlerElement(root.evalNode("typeHandlers"));
      //  mapper 处理
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

这段代码非常直观,一眼就能看出,标签对应的解析方法。

  • 本文作者: 小胡
  • 本文链接: http://myblog.run/archives/002-mybatisxml解析
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
000-mybatis源码分析-整体架构
003-mapper解析
  • 文章目录
  • 站点概览
小胡

小胡

5 日志
5 分类
0 标签
RSS
Creative Commons
© 2026 小胡
由 Halo 强力驱动
|
主题 - NexT.Gemini v5.1.4
渝ICP备20006930号