Mybatis源碼學習筆記(二) 配置介紹

配置介紹

在上篇文章的例子中,我們可以看到,Mybatis 通過SqlSessionFactory獲取SqlSession, 然後才能通過SqlSession與數據庫進行交互。

這裏寫圖片描述

所以我們要知道如何構建SqlSessionFactory的,通過下面這段代碼可以知道,是通過SqlSessionFactoryBuilder的build方法構建的。那麼,先從SqlSessionFactoryBuilder入手:

// Reader讀取mybatis配置文件,傳入構造方法 而這裏的Reader就是Resources.getResourceAsReader(resource)方法返回的
// 除了Reader外,其實還有對應的inputStream作爲參數的構造方法 就在這段源碼的下方 這裏暫時先不貼了
public SqlSessionFactory build(Reader reader) {
    return build(reader, null, null);
  }

  public SqlSessionFactory build(Reader reader, String environment) {
    return build(reader, environment, null);
  }

// mybatis配置文件 + properties, 此時mybatis配置文件中可以不配置properties,也能使用${}形式
  public SqlSessionFactory build(Reader reader, Properties properties) {
    return build(reader, null, properties);
  }

  public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      //XMLConfigBuilder  通過parse方法 來解析configuration.xml文件
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        reader.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

二、XMLConfigBuilder 類:

  // 構建一個 XMLConfigBuilder對象

  //這裏通過傳入一個reader 是否進行驗證的布爾值 Properties對象 XMLMapperEntityResolver對象(用來找到對應的dtd文件) 來構造一個XML解析器 XPathParser

  // 這個解析器中
  // private Document document;  用來解析xml文件
  // private boolean validation; 驗證
  // private EntityResolver entityResolver; 通過key查找dtd文件
  // private Properties variables;
  // private XPath xpath; 將元素轉換成爲節點信息

  // URL和mybatis的dtd文件用map做了一個映射,每個配置文件中有一個PUBLICID和SYSTEMID 這個是我們註冊的key 而EntityResolver是一個接口 實現這個接口可以去尋找dtd文件

  public XMLConfigBuilder(Reader reader, String environment, Properties props) { 
    this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
  }

 // 對解析器XPathParser environment Properties 對象進行初始化
  private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration());
    ErrorContext.instance().resource("SQL Mapper Configuration");
    // 將已配置的Properties屬性set到Configuration對象中
    // configuration這個對象會裝載所有解析mybatis配置文件的所有節點元素
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
  }

  public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    //從根節點 configuration 入手解析
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

  //從源碼中可以看出  configuration節點爲根節點

  // 在configuration節點之下,我們可以配置10個子節點, 分別爲:properties、typeAliases、plugins、objectFactory、objectWrapperFactory、settings、environments、databaseIdProvider、typeHandlers、mappers

  private void parseConfiguration(XNode root) {
    try {
      propertiesElement(root.evalNode("properties")); //issue #117 read properties first
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      settingsElement(root.evalNode("settings"));
      environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631
      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);
    }
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章