Mybatis 架构(-)基础层(1. 解析器模块)

Mybatis架构

1 基础支持层

1.1 解析器模块

配置文件xml 解析

1.1.1 常见的xml解析方式
  • DOM

基于属性结构的XML解析方式,将整个XML文档读入内存构建一个DOM树,基于树形结构对各节点进行操作

优点:易于编程,可以根据需求在树形结构的各节点之间导航,可以添加修改元素值

缺点:当文件较大时,会造成较大的资源消耗

适用:对XML内容多次随机读取或更改情况

  • SAX

​ 基于事件模型的XML解析方式,只需加载一部分到内存中,也不会记录XML中的数据,执行到某节点,会触发注册在该节点上的回调函数,需继承SAX提供的DefaultHandle基类,事件由解析器产生并通过回调函数发送给应该用程序,推模式。

优点: 所占用资源小

缺点:需要开发人员维护多层节点的关系,当文档比较复杂时,维护成本高,另外处理为流式处理,只能单向,没有提供写XML文档的功能,不支持XPath

适用:只扫描一次就能提取到想要数据的情况

  • StAX

​ 解析方式与SAX类似,基于事件模型,但采取的是 ”拉模式“,(Pull), 应用程序调用解析器进行解析

优点:简化应用程序处理XML的代码,可以同时处理多个XML文档, 既可以读,也可以写

缺点:不能读取已经读过的内容

适用:只扫描一次就能读取到想要数据的情况

1.1.2 XPath

一句话解析什么是XPath: XPath之于XML就好比SQL之于数据库

XPath 使用示例

public static void main(String[] args) throws Exception {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();

        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

        Document doc = documentBuilder.parse("src/com/zz/inventory.xml");

        XPathFactory factory = XPathFactory.newInstance();

        XPath xPath = factory.newXPath();

        XPathExpression expression = xPath.compile("//book[author='Neal Stephenson']/title/text()");

        Object evaluate = expression.evaluate(doc, XPathConstants.NODESET);

        NodeList nodeList = (NodeList) evaluate;

        for (int i = 0; i <nodeList.getLength(); i++) {
            System.out.println(nodeList.item(i).getNodeValue());
        }
    }
1.1.3 XPathParser

XPathParser是 Mybatis 封装了Document, XPath, EntityResolver

  • EntityResolver

(The application can also use this interface to redirect system identifiers to local URIs or to look up replacements in a catalog) 应用程序可以使用这个接口来重定向系统标识符通过本地URL或查找目录中的替换项

用来加载本地DTD文件,解析mybatis-config.xml 和 *mapper.xml

  • XPathParser 中的createDocument 封装了创建Document对象的方法
private Document createDocument(InputSource inputSource) {
    // important: this must only be called AFTER common constructor
    try {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      factory.setValidating(validation);

      factory.setNamespaceAware(false);
      factory.setIgnoringComments(true);
      factory.setIgnoringElementContentWhitespace(false);
      factory.setCoalescing(false);
      factory.setExpandEntityReferences(true);

      DocumentBuilder builder = factory.newDocumentBuilder();
      builder.setEntityResolver(entityResolver);
      builder.setErrorHandler(new ErrorHandler() {
        @Override
        public void error(SAXParseException exception) throws SAXException {
          throw exception;
        }

        @Override
        public void fatalError(SAXParseException exception) throws SAXException {
          throw exception;
        }

        @Override
        public void warning(SAXParseException exception) throws SAXException {
        }
      });
      return builder.parse(inputSource);
    } catch (Exception e) {
      throw new BuilderException("Error creating document instance.  Cause: " + e, e);
    }
  }

解析:示例${username:root}

​ XPathParser 中提供了一系列eval*() ,其中evalString() 方法,会处理默认值

public String evalString(Object root, String expression) {
    String result = (String) evaluate(expression, root, XPathConstants.STRING);
    result = PropertyParser.parse(result, variables);
    return result;
  }

PropertyParser (Property解析器)

public static String parse(String string, Properties variables) {
    VariableTokenHandler handler = new VariableTokenHandler(variables);
    GenericTokenParser parser = new GenericTokenParser("${", "}", handler);
    return parser.parse(string);
  }

使用了VariableTokenHandler 和 GenericTokenParser 完成占位符的解析。

GenericTokenParser 不仅用于此处默认值解析,还有用于动态SQL 解析,具体解析行为是由实现了TokenHandler 的类实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值