• Mybatis源码浅读一


        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        /**
         * 创建SqlSessionFactory工厂
         */
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
      //  List<User> list = session.selectList("org.apache.ibatis.test.pojo.UserDao.findAll");
         UserDao mapper = session.getMapper(UserDao.class);
       List list = mapper.findAll();

    1.我们先看着几行的代码(单独mybatis 运行,没有与spring整合)

      具体的流程是  :

        a.先创建sqlSession 的工厂

        b.通过sqlSession工厂得到SqlSession

        c.SqlSession通过代理的方式得到mapper接口的代理对象

        d.最后执行sql并得到结果集

    2.我们关注流程的入口

       SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        从这个的表面上看 我们只是创建了SqlSessionFactory  ,我们跟进源码看看

        

      public SqlSessionFactory build(InputStream inputStream) {
        return build(inputStream, null, null);
      }
      public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
        try {
          /**
           * 通过构造器得到XMLConfigBuilder 对象
           * environment  null
           * properties   null
           * inputStream
           */
          XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
          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.
          }
        }
      }
      public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
      }

    看了这几部分的代码实质就是new DefaultSqlSessionFactory()对象,并返回。

    我们虽然知道了SqlSessionFactory 的对象创建,但是我们更应该了解里面的构建过程

    public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
        try {
          /**
           * 通过构造器得到XMLConfigBuilder 对象
           * environment  null
           * properties   null
           * inputStream
           */
          XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
        //重点分析
    return build(parser.parse());
    public class XMLConfigBuilder extends BaseBuilder {
    
      private boolean parsed;
      /**
       * xml 解析器
       *
       *  private final Document document;   表示整个 HTML或XML文档
       *  private boolean validation;
       *  private EntityResolver entityResolver;   作用该xml文档上的声明,根据声明去寻找相应的dtd定义,以便对文档的进行验证,
       *  private Properties variables;   该类主要用于读取Java的配置文件
       *  private XPath xpath;   用于解析XML的工具类对象
       */
      private final XPathParser parser;
      private String environment;
      private final ReflectorFactory localReflectorFactory = new DefaultReflectorFactory();
    public class XPathParser {
      private final Document document;
      private boolean validation;
      private EntityResolver entityResolver;
      private Properties variables;
      private XPath xpath;

      mybatis将配置文件的数据解析封装到了Document(XMLConfigBuilder------>XPathParser------->Document)中

      我们跟进下return build(parser.parse());

      public Configuration parse() {
        if (parsed) {
          throw new BuilderException("Each XMLConfigBuilder can only be used once.");
        }
        parsed = true;
        parseConfiguration(parser.evalNode("/configuration"));
        return configuration;
      }

      

      /**
       * 这个方法规定了对文档解析的流程
       * @param root
       */
      private void parseConfiguration(XNode root) {
        try {
          // issue #117 read properties first
          propertiesElement(root.evalNode("properties"));
          Properties settings = settingsAsProperties(root.evalNode("settings"));
          loadCustomVfs(settings);
          loadCustomLogImpl(settings);
          typeAliasesElement(root.evalNode("typeAliases"));
          pluginElement(root.evalNode("plugins"));
          objectFactoryElement(root.evalNode("objectFactory"));
          objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
          reflectorFactoryElement(root.evalNode("reflectorFactory"));
          settingsElement(settings);
          // read it after objectFactory and objectWrapperFactory issue #631
          environmentsElement(root.evalNode("environments"));
          databaseIdProviderElement(root.evalNode("databaseIdProvider"));
          typeHandlerElement(root.evalNode("typeHandlers"));
          mapperElement(root.evalNode("mappers"));
        } catch (Exception e) {
          throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
        }
      }

    从这边我们可以知道这个方法对配置文件的每个属性节点的数据处理

    初始化Mybatis的过程其实就是构建 Configuration 这个对象,Configuration对象包含了Mybatis运行所需要的所有配置项

  • 相关阅读:
    不开心吗?那来看看这组治愈漫画吧!
    TF、Keras错误解决:TypeError: Cannot interpret feed_dict key as Tensor ...... is not an element of this graph.
    【JMeter】HTTP请求示例以及事务控制器的使用
    <%=BASE_URL%>根目录
    vue循环多个form表单,v-model绑定值一样的问题。
    vue 具名插槽
    vue 实现子组件改变数据,父组件实时更新 (使用.sync修饰符就可以实现)
    vue-cli3快速创建项目
    js关于Blob对象的使用
    AnyCAD C#开发-TopoShapeConvert辅助类TopoShape转换为SceneNode
  • 原文地址:https://www.cnblogs.com/liudingwei/p/15879280.html
Copyright © 2020-2023  润新知