MyBatis XMLMapperBuilder 是如何解析 SQL 映射文件的? 它读取了哪些信息?

XMLMapperBuilder 是 MyBatis 中负责解析 SQL 映射 XML 文件 的关键组件。 SQL 映射文件定义了 SQL 语句、参数映射、结果映射、缓存配置等信息,用于将 Java 方法调用映射到具体的 SQL 操作。 XMLMapperBuilder 的主要职责就是读取这些 XML 文件,解析其中的 SQL 映射配置,并将这些配置信息存储到 Configuration 对象中,供 MyBatis 运行时使用。

1. XMLMapperBuilder 如何解析 SQL 映射文件:

XMLMapperBuilder 的解析过程与 XMLConfigBuilder 类似,也主要依赖于 XPath 技术来定位和提取 XML 文件中的数据。 以下是 XMLMapperBuilder 解析 SQL 映射文件的详细步骤:

  • 1.1. 初始化 XMLMapperBuilder:

    XMLConfigBuilder 解析 <mappers> 元素时,如果 <mapper> 子元素指定了 resourceurl 属性 (指向 XML Mapper 文件),XMLConfigBuilder 会为每个 XML Mapper 文件创建一个 XMLMapperBuilder 实例,并将 Mapper XML 文件的 InputStreamReader 传递给它。

    java 复制代码
    // 在 XMLConfigBuilder 中,解析 <mapper resource="..."> 或 <mapper url="..."> 时会创建 XMLMapperBuilder
    XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource);
    • inputStreamReader: 用于读取 Mapper XML 文件的输入流或字符流。
    • configuration: XMLConfigBuilder 正在构建的 Configuration 对象。 XMLMapperBuilder 需要访问 Configuration 对象,以便将解析到的 Mapper 映射信息注册到 Configuration 中。
    • resource: Mapper XML 文件的资源路径 (例如 com/example/mapper/UserMapper.xml),用于日志记录和错误提示。
  • 1.2. 调用 XMLMapperBuilder.parse() 方法:

    XMLMapperBuilder 的核心解析方法也是 parse()。 调用 parse() 方法开始 SQL 映射文件的解析过程.

    java 复制代码
    mapperParser.parse();
  • 1.3. 使用 XPath 解析 XML 元素:

    XMLMapperBuilder.parse() 方法内部会使用 XPath 表达式 来定位和读取 Mapper XML 文件中的各个元素。 XPath 帮助解析器高效地访问和提取 XML 结构中的特定元素和属性。

    例如,要解析 <select> 元素,XMLMapperBuilder 可能会使用 XPath 表达式类似于 "mapper/select" 来定位 <select> 元素。

  • 1.4. 顺序解析 XML 元素 :

    XMLMapperBuilder 会按照一定的顺序解析 Mapper XML 文件中的元素,大致顺序如下 (与 Mapper XML 文件中元素的建议顺序一致):

    • <mapper> (根元素): 首先解析根元素 <mapper>,作为整个 Mapper 映射文件的入口。
    • <cache-ref>: 解析 <cache-ref> 元素,引用其他 Mapper 的缓存配置。
    • <cache>: 解析 <cache> 元素,配置 Mapper 级别的缓存。
    • <resultMap>: 解析 <resultMap> 元素,定义结果集映射。
    • <parameterMap> (已过时): 解析 <parameterMap> 元素 (已过时,不推荐使用,通常使用内联参数映射)。
    • <sql>: 解析 <sql> 元素,定义可重用的 SQL 片段。
    • <select>, <insert>, <update>, <delete>: 解析 <select>, <insert>, <update>, <delete> 元素,定义 SQL 查询、插入、更新、删除语句。
  • 1.5. 构建 MappedStatement 对象并注册到 Configuration:

    对于每个解析到的 <select>, <insert>, <update>, <delete> 元素,XMLMapperBuilder 会根据 XML 元素的内容,构建一个 MappedStatement 对象MappedStatement 对象封装了 SQL 语句的所有相关信息,例如:

    • SQL 语句文本 (经过动态 SQL 处理)。
    • SQL 语句类型 (SELECT, INSERT, UPDATE, DELETE)。
    • 参数类型 (parameterType)。
    • 结果类型或结果映射 (resultType, resultMap)。
    • 缓存配置 (useCache, flushCache)。
    • 超时时间 (timeout)。
    • Statement 类型 (STATEMENT, PREPARED, CALLABLE)。
    • FetchSize, ResultSetType, 等其他 JDBC 相关配置。

    构建好 MappedStatement 对象后,XMLMapperBuilder 会将其 注册到 Configuration 对象的 mapperRegistry 属性 (一个 MapperRegistry 对象) 中 。 注册时,会使用 Mapper 接口的全限定名 + SQL 语句的 id 属性作为 MappedStatement 的唯一 ID (mappedStatementId)。 例如,如果 Mapper 接口是 com.example.mapper.UserMapper<select id="getUserById"> 语句的 mappedStatementId 将是 com.example.mapper.UserMapper.getUserById

  • 1.6. 注册 Mapper 接口到 Configuration (如果 Mapper XML 文件关联了 Mapper 接口):

    如果 Mapper XML 文件的 <mapper namespace="..."> 元素指定了 Mapper 接口的命名空间 (namespace),XMLMapperBuilder 还会将对应的 Mapper 接口注册到 Configuration 对象的 mapperRegistry 中。 这样,MyBatis 才能在运行时根据 Mapper 接口找到对应的 SQL 映射配置。

  • 1.7. 完成解析:

    XMLMapperBuilder.parse() 方法完成 SQL 映射文件的解析和注册后,解析过程结束。

2. XMLMapperBuilder 读取了哪些信息 (XML 元素及其含义):

XMLMapperBuilder 主要读取和解析 SQL 映射 XML 文件中的以下信息:

  • <mapper>: 根元素,定义 Mapper 映射文件的命名空间 (namespace)。

    • 读取信息:
      • namespace 属性:Mapper 接口的命名空间 (全限定名)。
    • 存储到 Configuration 对象: 用于确定 Mapper 接口和 SQL 映射之间的关联关系,以及构建 MappedStatement 的 ID。
  • <cache-ref>:

    • 作用: 引用其他 Mapper 的缓存配置,实现缓存共享。
    • 读取信息:
      • namespace 属性:被引用的 Mapper 的命名空间。
    • 存储到 Configuration 对象: 将缓存引用信息存储到当前 Mapper 的 cache 属性 (一个 Cache 对象) 中,指向被引用 Mapper 的缓存。
  • <cache>:

    • 作用: 配置 Mapper 级别的缓存,用于提高查询性能。
    • 读取信息:
      • type 属性 (可选):缓存实现类型 (例如 PERPETUAL, LRU, FIFO, WEAK, SOFT, 或自定义缓存实现类)。 默认 PERPETUAL
      • eviction 属性 (可选):缓存回收策略 (例如 LRU, FIFO, WEAK, SOFT)。 默认 LRU
      • flushInterval 属性 (可选):缓存刷新间隔 (毫秒)。
      • size 属性 (可选):缓存大小 (对象个数)。
      • readOnly 属性 (可选):是否只读缓存 (true/false)。 默认 false
      • blocking 属性 (可选):是否阻塞缓存 (true/false)。 默认 false
      • <property> 子元素 (可选):缓存实现类的自定义属性。
    • 存储到 Configuration 对象: 根据配置信息创建 Cache 接口的实现类实例,并将其设置到当前 Mapper 的 cache 属性 (一个 Cache 对象) 中。
  • <resultMap>:

    • 作用: 定义复杂的结果集映射规则,用于将查询结果列映射到 Java 对象属性。
    • 读取信息:
      • id 属性:resultMap 的唯一 ID。
      • type 属性:结果映射的目标 Java 类型。
      • extends 属性 (可选):继承自其他 resultMap
      • autoMapping 属性 (可选):是否开启自动映射 (true/false, partial/full, 默认 true)。
      • <constructor> 子元素 (可选):配置构造器注入。
      • <id> 子元素:配置主键映射。
      • <result> 子元素:配置普通属性映射。
      • <association> 子元素:配置关联对象映射 (一对一)。
      • <collection> 子元素:配置集合属性映射 (一对多)。
      • <discriminator> 子元素:配置鉴别器映射 (用于多态映射)。
    • 存储到 Configuration 对象: 根据配置信息创建 ResultMap 对象,并将其注册到 Configuration 对象的 resultMapRegistry 属性 (一个 ResultMapRegistry 对象) 中,使用 resultMapid 作为 key。
  • <parameterMap> (已过时):

    • 作用: 已过时的参数映射配置方式,不推荐使用,通常使用内联参数映射 (#{}${})。
    • 读取信息:
      • id 属性:parameterMap 的 ID。
      • type 属性:参数类型。
      • <parameter> 子元素:配置参数映射。
    • 存储到 Configuration 对象: 如果存在 <parameterMap>,会创建 ParameterMap 对象并注册到 Configuration 对象的 parameterMapRegistry 属性 (一个 ParameterMapRegistry 对象) 中,使用 parameterMapid 作为 key。 但通常不推荐使用 parameterMap,现代 MyBatis 开发中几乎不用。
  • <sql>:

    • 作用: 定义可重用的 SQL 片段,可以在多个 SQL 语句中引用,提高 SQL 复用性。
    • 读取信息:
      • id 属性:sql 片段的唯一 ID。
      • SQL 语句内容 (CDATA 或普通文本)。
    • 存储到 Configuration 对象:<sql> 元素定义的 SQL 片段 (SqlNode 对象) 存储到 Configuration 对象的 sqlFragments 属性 (一个 Map<String, XNode>) 中,使用 sql 片段的 id 作为 key。
  • <select>, <insert>, <update>, <delete>:

    • 作用: 定义 SQL 查询、插入、更新、删除语句,并将 Java 方法与 SQL 语句关联起来。

    • 读取信息 (通用属性):

      • id 属性:SQL 语句的唯一 ID (在 Mapper 命名空间内唯一)。
      • parameterType 属性 (可选):参数类型。
      • parameterMap 属性 (可选, 已过时):参数映射引用 (不推荐使用)。
      • resultType 属性 (可选):结果类型。
      • resultMap 属性 (可选):结果映射引用。
      • flushCache 属性 (可选):是否刷新缓存 (true/false)。 默认值取决于 SQL 类型 (SELECT: false, 其他: true)。
      • useCache 属性 (可选, 仅 <select> 有效):是否使用二级缓存 (true/false)。 默认 true
      • timeout 属性 (可选):超时时间 (秒)。
      • fetchSize 属性 (可选):JDBC Fetch Size。
      • statementType 属性 (可选):Statement 类型 (STATEMENT, PREPARED, CALLABLE)。 默认 PREPARED
      • resultSetType 属性 (可选):ResultSet 类型 (FORWARD_ONLY, SCROLL_SENSITIVE, SCROLL_INSENSITIVE)。
      • databaseId 属性 (可选):数据库 ID,用于多数据库支持。
      • lang 属性 (可选):语言驱动器 (例如 XML, RAW, 默认 XML)。
      • SQL 语句内容 (CDATA 或普通文本,可以包含动态 SQL 标签)。
    • 读取信息 (<select>):

      • keyProperty 属性 (可选):用于指定主键属性,用于缓存管理。
      • keyColumn 属性 (可选):用于指定主键列名,用于缓存管理。
      • resultOrdered 属性 (可选):结果是否排序 (true/false)。 默认 false
      • resultSetType 属性 (可选):ResultSet 类型 (FORWARD_ONLY, SCROLL_SENSITIVE, SCROLL_INSENSITIVE)。
      • cursorName 属性 (可选):游标名称 (用于存储过程)。
    • 读取信息 (<insert>, <update>, <delete>):

      • keyGenerator 属性 (可选, <insert> 有效):主键生成器类型 (例如 JDBC, SELECT KEY, CUSTOM)。
      • keyProperty 属性 (可选, <insert> 有效):主键属性名 (用于获取生成的主键值)。
      • keyColumn 属性 (可选, <insert> 有效):主键列名 (用于获取生成的主键值)。
      • useGeneratedKeys 属性 (可选, <insert> 有效):是否使用 JDBC 的 getGeneratedKeys 获取主键 (true/false)。 默认 false
      • parameterType 属性 (可选, <update>, <delete> 可以省略,从方法签名推断)。
    • 存储到 Configuration 对象: 对于每个 <select>, <insert>, <update>, <delete> 元素,XMLMapperBuilder 会根据解析到的信息,创建一个 MappedStatement 对象,并将其注册到 Configuration 对象的 mappedStatements 属性 (一个 StrictMap<MappedStatement>) 中,使用 Mapper 命名空间 + SQL 语句 ID 作为 key。

总结:

XMLMapperBuilder 是 MyBatis SQL 映射文件的解析引擎。 它使用 XPath 技术高效地解析 Mapper XML 文件,读取 SQL 语句、参数映射、结果映射、缓存配置等信息,并将这些信息封装在 MappedStatement, ResultMap, Cache 等对象中。 最终,这些对象会被注册到 Configuration 对象中,构成 MyBatis 运行时 SQL 映射配置的核心部分。

相关推荐
A__tao1 小时前
在线 SQL 转 Flask-SQLAlchemy
数据库·sql·flask
yuyuyuliang002 小时前
Qt SQL-1
sql·qt
bing_1583 小时前
MyBatis SqlSession 是如何创建的? 它与 SqlSessionFactory 有什么关系?
mybatis
bing_1586 小时前
MyBatis 如何解析 XML 配置文件和 SQL 映射文件
mybatis
后端小肥肠8 小时前
GitHub星标20K!Chat2DB:用说人话的方式写SQL
数据库·sql·openai
一线大码12 小时前
关于 LEFT JOIN 的使用注意事项
后端·sql·mysql
chat2tomorrow12 小时前
QuickAPI:一键将 Excel 数据转为数据库表
数据库·sql·mysql·oracle·excel·统一数据服务·sql2api
StevenLdh16 小时前
StarRocks SQL使用与MySql的差异及规范注意事项
数据库·starrocks·sql·mysql
IT邦德17 小时前
Navicat又放大招,接入DeepSeek后AI写SQL
数据库·人工智能·sql