配置介紹
在上篇文章的例子中,我們可以看到,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);
}
}