当前位置: 首页 > article >正文

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 传递给它。

    // 在 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 映射文件的解析过程.

    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 映射配置的核心部分。


http://www.kler.cn/a/589519.html

相关文章:

  • docker安装rabbitmq
  • pyyaml_include 2.x 版本使用说明
  • Spring Cloud Gateway 生产级实践:高可用 API 网关架构与流量治理解析
  • Linux应用软件编程(多任务:进程间通信)
  • Excel VBA实现智能合并重复元器件数据(型号去重+数量累加)
  • VSCode C/C++ 环境搭建指南
  • 云原生服务网格:微服务通信的神经中枢革命
  • 【AI知识管理系统】(一)AI知识库工具测评
  • 美颜SDK x AIGC:如何用滤镜API结合AI生成技术打造创意视觉特效?
  • CI/CD构建与注意事项
  • gazebo报错:[Err] [InsertModelWidget.cc:302] Missing model.config for model
  • 【最佳实践】Go 状态模式
  • 蓝桥杯学习-11栈
  • Gone v2 Tracer 组件-给微服务提供统一的traceID
  • 深入解析Java面向对象三大特征之多态、final、抽象类与接口
  • CMake学习笔记(二):变量设值,源文件/文件查找
  • 网络安全运维应急响应与溯源分析实战案例
  • 【ES6】01-ECMAScript基本认识 + 变量常量 + 数据类型
  • Java高效构建树形结构——异步加载子节点的实现方案
  • “Failed to Load SteamUI.dll” 错误详解:全面解析与高效解决方案,助你快速修复 Steam 客户端问题