MyBatis源码分析之基础支持层解析器

(/≧▽≦)/~┴┴ 嗨~我叫小奥 ✨✨✨
👀👀👀 个人博客:小奥的博客
👍👍👍:个人优快云
⭐️⭐️⭐️:传送门
🍹 本人24应届生一枚,技术和水平有限,如果文章中有不正确的内容,欢迎多多指正!
📜 欢迎点赞收藏关注哟! ❤️

解析器模块

解析器模块主要提供了两个功能:

  • 为解析MyBatis配置文件、Mapper映射文件等提供支持
  • 为处理动态SQL语句中的占位符提供支持

MyBatis的解析器模块目录如下:

在这里插入图片描述

主要包路径:org.apache.ibatis.parsing

解析器模块的包结构如上图所示,其中,XPathParser 和XNode 主要用来解析 XML,PropertyParser、GenericTokenParser 、TokenHandler 主要用于标记处理(占位符),ParsingException是异常处理类。

  • GenericTokenParser:通用的Token解析器(即占位符解析器),解析xml文件中的占位符${},并返回对应的值
  • ParsingException:异常处理类
  • PropertyParser:动态属性解析器
  • TokenHandler:标记处理接口
  • XNode:XML节点,封装了Node
  • XPathParser:基于Java XPath 解析器,用于解析MyBatis的mybatis-config.xmlMapper.xml等XML配置文件

① TokenHandler

TokenHandler是一个接口,定义了一个handleToken方法,该方法主要用于标记处理,具体实现在各自实现类中完成。主要是配合通用标记解析器GenericTokenParser类完成对配置文件等的解析工作,其中TokenHandler主要完成处理,而解析器主要实现前序工作——解析。

public interface TokenHandler {
   
  /**
   * 标记处理接口
   * @param content
   * @return
   */
  String handleToken(String content);
}

② XNode

XNode作为解析xml配置文件的基础类,其中封装了Node节点,并且提供了常见的解析一个Node节点需要的功能和方法。

public class XNode {
   

  private final Node node; // mark 被包装的org.w3c.dom.Node对象
  private final String name; // mark 节点名称
  private final String body; // mark 节点内容
  private final Properties attributes; // mark 节点属性集合
  private final Properties variables; // mark 配置文件中<properties>节点下定义的键值对
  private final XPathParser xpathParser; // mark 封装了XPath解析器,负责XNode对象的生成,并提供解析XPath表达式的功能

  public XNode(XPathParser xpathParser, Node node, Properties variables) {
   
    this.xpathParser = xpathParser;
    this.node = node;
    this.name = node.getNodeName();
    this.variables = variables;
    this.attributes = parseAttributes(node);
    this.body = parseBody(node);
  }

  public XNode newXNode(Node node) {
   
    return new XNode(xpathParser, node, variables); // mark 根据传入的Node对象,创建XNode对象实例
  }

  /**
   * 获取父节点
   * @return 父节点是Element类型,返回封装好的XNode节点,否则返回null
   */
  public XNode getParent() {
   
    Node parent = node.getParentNode();
    if (!(parent instanceof Element)) {
   
      return null;
    }
    return new XNode(xpathParser, parent, variables);
  }

  /**
   * 获取节点路径
   * @return 节点的路径值
   *         比如 <A><B><C><C/><B/><A/>,对于C节点来说节点路径就是 A/B/C
   */
  public String getPath() {
   
    StringBuilder builder = new StringBuilder();
    Node current = node; // mark 当前节点
    while (current instanceof Element) {
   
      if (current != node) {
   
        builder.insert(0, "/");
      }
      builder.insert(0, current.getNodeName());
      current = current.getParentNode(); // mark 向上追溯节点,直到顶层节点
    }
    return builder.toString();
  }

  /**
   * 获取节点的识别码
   * @return 返回唯一标识字符串,如下面的C节点的唯一标识字符串就是 A_B[bid]_C[cid]
   * @Code <A>
   *          <B id="bid">
   *              <C id="cid" value="cvalue"/>
   *          </B>
   *      </A>
   */
  public String getValueBasedIdentifier() {
   
    StringBuilder builder = new StringBuilder();
    XNode current = this;
    while (current != null) {
   
      if (current != this) {
   
        builder.insert(0, "_");
      }
      String value = current.getStringAttribute("id",
          current.getStringAttribute("value", current.getStringAttribute("property", (String) null)));
      if (value != null) {
   
        value = value.replace('.', '_');
        builder.insert(0, "]");
        builder.insert(0, value);
        builder.insert(0, "[");
      }
      builder.insert(0, current.getName());
      current = current.getParent();
    }
    return builder.toString();
  }

  /**
   *  evalXXX()方法,调用XPathParser方法在当前节点下寻找符合表达式条件的节点,通常是文本节点,并
   *  将值转为为指定的类型,如果值无法转化为指定类型,则会报错。
   *  【支持数据类型】 String、Boolean、Double、Node、List<Node>
   */

  ...

  /**
   * getXXXBody()方法:获取文本内容并将其转化为指定的数据类型
   * 【支持的数据类型】String、Boolean、Integer、Long、Double、Float
   */
	...

  /**
   * getXxxAttribute()方法:获取节点指定属性的属性值并将其转化为指定的数据类型
   */
	...

  /**
   * 获取子节点,对Node.getChildNodes()做相应的封装得到List<XNode>
   * @return 子节点集合
   */
  public List<XNode> getChildren() {
   
    List<XNode> children = 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值