zoukankan      html  css  js  c++  java
  • Mybatis初始化过程

    学习自拉钩教育java高薪训练营

    Mybatis初始化过程

    // 1. 读取配置文件,读成字节输入流,注意:现在还没解析
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    
    // 2. 解析配置文件,封装Configuration对象   创建DefaultSqlSessionFactory对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    

    image-20201116211910024

    1.读取配置文件,读成字节输入流

    //Resources.java
    public static InputStream getResourceAsStream(String resource) throws IOException {
        return getResourceAsStream(null, resource);
    }
    
    public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
        InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader);
        if (in == null) {
            throw new IOException("Could not find resource " + resource);
        }
        return in;
    }
    

    通过classLoad调用getResourceAsStream()方法返回字节输入流,也就是得到了配置文件的字节输入流

    2. 解析配置文件,封装Configuration对象 创建DefaultSqlSessionFactory对象

    2.1 解析配置文件

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    
    //SqlSessionFactoryBuilder.java
    
    // 1.我们最初调用的build
    public SqlSessionFactory build(InputStream inputStream) {
        //调用了重载方法
        return build(inputStream, null, null);
    }
    
    // 2.调用的重载方法
    public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
        try {
            // 创建 XMLConfigBuilder, XMLConfigBuilder是专门解析mybatis的配置文件的类
            XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
            // 执行 XML 解析
            // 创建 DefaultSqlSessionFactory 对象
            return build(parser.parse());
        } catch (Exception e) {
            throw ExceptionFactory.wrapException("Error building SqlSession.", e);
        } finally {
            ErrorContext.instance().reset();
            try {
                inputStream.close();
            } catch (IOException e) {
                // Intentionally ignore. Prefer previous error.
            }
        }
    }
    

    1.传入配置文件的字节输入流,调用其重载方法。
    2.创建 XMLConfigBuilder对象,它是用来解析mybatis的配置文件的类
    3.执行parser.parse()

    parser.parse()
    //XMLConfigBuilder.java
    /**
     * 解析 XML 成 Configuration 对象。
     *
     * @return Configuration 对象
     */
    public Configuration parse() {
        // 若已解析,抛出 BuilderException 异常
        if (parsed) {
            throw new BuilderException("Each XMLConfigBuilder can only be used once.");
        }
        // 标记已解析
        parsed = true;
        ///parser是XPathParser解析器对象,读取节点内数据,<configuration>是MyBatis配置文件中的顶层标签
        // 解析 XML configuration 节点
        parseConfiguration(parser.evalNode("/configuration"));
        return configuration;
    }
    

    parse():
    判断是否解析过,抛出异常或打标记
    4.调用parseConfiguration()方法,开始解析XML configuration 节点,并返回configuration

    //XMLConfigBuilder.java
    /**
     * 解析 XML
     * 具体 MyBatis 有哪些 XML 标签,参见 《XML 映射配置文件》http://www.mybatis.org/mybatis-3/zh/configuration.html
     * @param root 根节点
     */
    private void parseConfiguration(XNode root) {
        try {
            //issue #117 read properties first
            // 解析 <properties /> 标签
            propertiesElement(root.evalNode("properties"));
            // 解析 <settings /> 标签
            Properties settings = settingsAsProperties(root.evalNode("settings"));
            // 加载自定义的 VFS 实现类
            loadCustomVfs(settings);
            // 解析 <typeAliases /> 标签
            typeAliasesElement(root.evalNode("typeAliases"));
            // 解析 <plugins /> 标签
            pluginElement(root.evalNode("plugins"));
            // 解析 <objectFactory /> 标签
            objectFactoryElement(root.evalNode("objectFactory"));
            // 解析 <objectWrapperFactory /> 标签
            objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
            // 解析 <reflectorFactory /> 标签
            reflectorFactoryElement(root.evalNode("reflectorFactory"));
            // 赋值 <settings /> 到 Configuration 属性
            settingsElement(settings);
            // read it after objectFactory and objectWrapperFactory issue #631
            // 解析 <environments /> 标签
            environmentsElement(root.evalNode("environments"));
            // 解析 <databaseIdProvider /> 标签
            databaseIdProviderElement(root.evalNode("databaseIdProvider"));
            // 解析 <typeHandlers /> 标签
            typeHandlerElement(root.evalNode("typeHandlers"));
            // 解析 <mappers /> 标签
            mapperElement(root.evalNode("mappers"));
        } catch (Exception e) {
            throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
        }
    }
    

    这些都是mybatis配置文件中的标签,开始逐个解析,注意最后一行 mapperElement(root.evalNode("mappers"))
    说明在解析config*.xml的同时也解析了mapper.xml(映射配置)文件
    一个映射配置文件中的每一个select、delete、update、insert都会封装成一个MappedStatement

    2.2.创建DefaultSqlSessionFactory对象

    return build(parser.parse());
    
    public SqlSessionFactory build(Configuration config) {
       return new DefaultSqlSessionFactory(config); //构建者设计模式
    }
    

    5.执行build方法,接收到封装好的Configuration对象,并根据这个对象构建一个DefaultSqlSessionFactoryDefaultSqlSessionFactory就是一个SqlSessionFactory的实现类。

    构建者设计模式:当构建一个复杂的对象时 可以把他拆成构建个很多的简单的对象,再由多个简单的对象构成复杂的对象

  • 相关阅读:
    Linux 学习手记(4):Linux系统常用Shell命令
    Linux 学习手记(3):Linux基本的文件管理操作
    Nginx的启动、停止与重启
    20个常用正则表达式
    MongoDB增删改查实例
    MongoDB 查询总结
    MongoDB数据库未授权访问漏洞及加固
    MongoDB安装
    java模拟post方式提交表单实现图片上传【转】
    Java图片处理 Thumbnails框架
  • 原文地址:https://www.cnblogs.com/isdxh/p/13994822.html
Copyright © 2011-2022 走看看