MyBatis 如何解析 XML 配置文件和 SQL 映射文件

MyBatis 使用 SAX(Simple API for XML)解析器来解析 XML 文件,SAX 是一种基于事件驱动的 XML 解析方式,具有高效、低内存消耗的优点。

MyBatis 主要解析两种类型的 XML 文件:

  1. 核心配置文件 (mybatis-config.xml): 定义 MyBatis 的全局配置信息,如数据源、事务管理器、类型别名、类型处理器、插件、映射器等。
  2. SQL 映射文件 (例如 UserMapper.xml): 定义 SQL 语句和映射规则,将 SQL 语句与 Mapper 接口的方法关联起来。

解析过程概述:

  1. 创建 XMLConfigBuilder (解析核心配置文件):

    • SqlSessionFactoryBuilder 的 build() 方法会创建一个 XMLConfigBuilder 对象,用于解析核心配置文件。
    • XMLConfigBuilder 内部会创建一个 SAX 解析器 (XMLMapperEntityResolver)。
    • XMLConfigBuilder 会解析核心配置文件中的各个元素(<properties>, <settings>, <typeAliases>, <typeHandlers>, <plugins>, <environments>, <mappers> 等),并将解析结果存储到 Configuration 对象中。
  2. 创建 XMLMapperBuilder (解析 SQL 映射文件):

    • 在解析核心配置文件中的 <mappers> 元素时,XMLConfigBuilder 会为每个 SQL 映射文件创建一个 XMLMapperBuilder 对象。
    • XMLMapperBuilder 内部也会创建一个 SAX 解析器。
    • XMLMapperBuilder 会解析 SQL 映射文件中的各个元素(<mapper>, <select>, <insert>, <update>, <delete>, <resultMap>, <sql> 等),并将解析结果转换为 MappedStatement 对象,并添加到 Configuration 对象的 mappedStatements 集合中。
  3. 使用 XPath 解析 XML 元素:

    • MyBatis 使用 XPath 表达式来定位和解析 XML 文件中的各个元素。
    • XMLConfigBuilder 和 XMLMapperBuilder 都使用 XPathParser 来解析 XPath 表达式。

核心配置文件 (mybatis-config.xml) 解析过程 (XMLConfigBuilder):

  1. 解析 <properties> 元素:

    • 读取 <properties> 标签的 resource 或 url 属性,加载外部属性文件。
    • 解析 <properties> 标签内部的 <property> 子元素,获取属性名和属性值。
    • 将属性存储到 Configuration 对象的 variables 属性中(一个 Properties 对象)。
  2. 解析 <settings> 元素:

    • 解析 <settings> 标签内部的 <setting> 子元素,获取设置名和设置值。
    • 将设置存储到 Configuration 对象的相应属性中(例如,cacheEnabled、lazyLoadingEnabled 等)。
  3. 解析 <typeAliases> 元素:

    • 解析 <typeAliases> 标签内部的 <typeAlias> 子元素,获取别名和对应的 Java 类型。
    • 解析 <typeAliases> 标签内部的 <package> 子元素,扫描指定包下的所有类,并自动生成别名(类名首字母小写)。
    • 将别名和类型注册到 Configuration 对象的 typeAliasRegistry 中。
  4. 解析 <typeHandlers> 元素:

    • 解析 <typeHandlers> 标签内部的 <typeHandler> 子元素,获取类型处理器类名(或实例)。
    • 解析 <typeHandlers> 标签内部的 <package> 子元素,扫描指定包下的所有类型处理器类。
    • 将类型处理器注册到 Configuration 对象的 typeHandlerRegistry 中。
  5. 解析 <objectFactory> 元素:

    • 解析<objectFactory>的type属性,获取对象工厂实现类。
    • 反射创建其实例,并设置到Configuration对象。
  6. 解析 <plugins> 元素:

    • 解析 <plugins> 标签内部的 <plugin> 子元素,获取插件类的全限定名。
    • 创建插件实例,并将插件添加到 Configuration 对象的 interceptorChain 中。
  7. 解析 <environments> 元素:

    • 解析 <environments> 标签的 default 属性,获取默认的环境 ID。
    • 解析 <environments> 标签内部的 <environment> 子元素,获取环境 ID、事务管理器配置和数据源配置。
    • 根据配置创建 TransactionFactory 和 DataSourceFactory,并创建相应的 Transaction 和 DataSource 实例。
    • 将环境配置存储到 Configuration 对象的 environment 属性中。
  8. 解析<databaseIdProvider>元素:

    • 解析<databaseIdProvider>的type属性,获取数据库厂商标识提供类。
    • 解析其内部<property>子元素,获取不同数据库对应的标识。
  9. 解析 <mappers> 元素:

    • 解析 <mappers> 标签内部的 <mapper> 子元素,获取 SQL 映射文件的路径(resource、url 或 class 属性)。
    • 解析 <mappers> 标签内部的 <package> 子元素,扫描指定包下的所有 Mapper 接口或 XML 映射文件。
    • 对于每个 SQL 映射文件,创建一个 XMLMapperBuilder 对象,并调用其 parse() 方法解析 SQL 映射文件。

SQL 映射文件 (例如 UserMapper.xml) 解析过程 (XMLMapperBuilder):

  1. 解析 <mapper> 元素:

    • 获取 <mapper> 标签的 namespace 属性,作为 Mapper 接口的全限定名。
  2. 解析 <cache> 元素(如果有):

    • 解析<cache>标签,获取缓存配置信息,创建Cache对象。
  3. 解析 <parameterMap> 元素(已废弃,不建议使用):

  • 解析 <parameterMap> 标签及其子元素,获取参数映射信息。
  1. 解析 <resultMap> 元素:

    • 解析 <resultMap> 标签及其子元素(<id>, <result>, <association>, <collection>, <discriminator>),获取结果映射规则。
    • 创建 ResultMap 对象,并添加到 Configuration 对象的 resultMaps 集合中。
  2. 解析 <sql> 元素:

    • 解析 <sql> 标签,获取可重用的 SQL 片段。
    • 将 SQL 片段存储到 Configuration 对象的 sqlFragments 集合中。
  3. 解析 <select>, <insert>, <update>, <delete> 元素:

    • 解析这些标签的属性(id, parameterType, resultType, resultMap, statementType, flushCache, useCache, timeout 等)。
    • 解析 SQL 语句内容,处理占位符(#{} 和 ${})。
    • 创建 MappedStatement 对象,并将 SQL 语句、参数类型、结果类型、SQL 类型(SELECT, INSERT, UPDATE, DELETE)等信息存储到 MappedStatement 对象中。
    • 将 MappedStatement 对象添加到 Configuration 对象的 mappedStatements 集合中。

关键类:

  • XMLConfigBuilder: 负责解析核心配置文件。
  • XMLMapperBuilder: 负责解析 SQL 映射文件。
  • XPathParser: 用于解析 XPath 表达式。
  • Configuration: 保存 MyBatis 的全局配置信息,以及解析后的 MappedStatement、ResultMap 等对象。
  • MappedStatement: 代表一个 SQL 语句,包含了 SQL 语句的 ID、参数类型、结果类型、SQL 语句内容等信息。
  • ResultMap: 代表一个结果映射规则,定义了如何将查询结果集映射为 Java 对象。

总结:

MyBatis 使用 SAX 解析器和 XPath 表达式来解析 XML 配置文件。XMLConfigBuilder 负责解析核心配置文件,XMLMapperBuilder 负责解析 SQL 映射文件。解析后的配置信息存储在 Configuration 对象中,MappedStatement 对象代表 SQL 语句,ResultMap 对象代表结果映射规则。

相关推荐
bksczm1 天前
Redis 持久化:RDB 快照与 AOF 日志
数据库·redis·mybatis
CoderYanger2 天前
Java EE 进阶:8.MyBatis 操作数据库(入门)(第二弹)
java·数据库·spring boot·spring·面试·java-ee·mybatis
CoderYanger5 天前
Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)
java·数据库·spring·面试·职场和发展·java-ee·mybatis
真上帝的左手7 天前
30. 技术专题-‌应用框架组件-关系型数据库-MySQL-Mybatis
数据库·分布式·mysql·中间件·mybatis
雪芽蓝域zzs7 天前
第 2 章:整合 MySQL + MyBatis,搭建数据库基础、实体类、Mapper、测试查询
数据库·mysql·mybatis
wljt8 天前
公司二-面试题
java·开发语言·mybatis
VimorphTech8 天前
文本已经改了,旧的音频生成结果还能回写吗?
java·数据库·mybatis
麻瓜code8 天前
双写一致性:为什么是“删缓存“,而不是“改缓存“
java·缓存·mybatis
郭小李9 天前
mybatis 动态 sql
java·sql·mybatis
知守观9 天前
技术考古:iBATIS 2.3.4 时代的持久层,是如何用 Map 玩转 307 个存储过程的?
java·后端·mybatis