1. 程式人生 > 其它 >MyBatis配置檔案解析_屬性節點properties的處理

MyBatis配置檔案解析_屬性節點properties的處理

properties子元素

properties子元素是MyBatis配置檔案中的第一個子元素,用來指向一個屬性檔案,它在XML檔案中的配置如下。

<properties resource="db.properties" url="路徑">
    <!-- 可以定義自已的property -->
    <property name="db" value="mysql"></property>
    <property name="url" value="jdbc:mysql"></property>
</properties>

在mybatis初始化時,會讀出resource或url指向的資源,儲存到一個Properties物件中。Configuration物件有一個Property的屬性variables,合併這兩個Properties物件,儲存到Configuration物件中,並下沉到其他所需的物件中,如XPathParser及XNode都儲存了這個物件,以備用。

XMLConfigBuilder中解析properties子元素的方法

XMLConfigBuilder中解析properties子元素的方法是private void propertiesElement(XNode context),其程式碼與基本流程如下:

// 解析子元素properties程式碼
private void propertiesElement(XNode context) throws Exception {
  // 若配置檔案中沒有子標籤**properties**則不作任何處理    
  if (context != null) {
    // 讀出所有的property子標籤,並讀到一個屬性(Properties)物件defaults  
    Properties defaults = context.getChildrenAsProperties();
    // 獲得屬性resource及url的值  
    String resource = context.getStringAttribute("resource");
    String url = context.getStringAttribute("url");
    // resource屬性與url屬性不能同時存在,若同時不空,則丟擲異常**BuilderException**,可以同時為null
    if (resource != null && url != null) {
      throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference.  Please specify one or the other.");
    }
    // 獲得resource或url中的資源表示的Properties物件,併合併到defaluts物件中  
    if (resource != null) {
      defaults.putAll(Resources.getResourceAsProperties(resource));
    } else if (url != null) {
      defaults.putAll(Resources.getUrlAsProperties(url));
    }
    // 若Configuration的vairables中已有值,一併合併到defaults中  
    Properties vars = configuration.getVariables();
    if (vars != null) {
      defaults.putAll(vars);
    }
    // 將完整的屬性物件(Configuration中已有的屬性物件,resource或url資源表示的屬性物件,及properties下property對應的屬性物件)
    // 儲存到parser物件及configuration物件中  
    // XPathParser在解析屬性值時,會處理${name},name對應的值中正是從這個variables中獲取的  
    parser.setVariables(defaults);
    configuration.setVariables(defaults);
  }
}

Configuration屬性variables的初值

初值可以從外部傳入,即使用者傳入,在呼叫SqlSessionFactoryBuilder的build方法時,客戶可以傳入一個Properties物件,作為Configuration屬性variables的初值,具體程式碼如下:

// SqlSessionFactoryBuilder上的方法,客戶可以傳入一個Properties物件,這個物件會作為Configuration屬性variables的初值
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
  try {
    //properties物件下沉到XMLConfigBuilder物件  
    XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
    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構造方法
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration());
    ErrorContext.instance().resource("SQL Mapper Configuration");
    // 這裡將處部傳入的屬性物件作為Configuration的variables的初值
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
}