本篇文章我們首先解析 SqlSessionFactory 的創(chuàng)建過程。
1、實(shí)例代碼
在實(shí)例代碼中,我們?cè)跍y(cè)試類中寫了一個(gè) init() 方法,里面包括了 SqlSessionFactory 的構(gòu)建,分為兩步。
第一步:讀取配置文件 mybatis-config.xml 輸入流
第二步:根據(jù)輸入流構(gòu)建 SqlSessionFactory;
public void init() {
//定義mybatis全局配置文件
String resource = "mybatis-config.xml";
//加載 mybatis 全局配置文件
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
//構(gòu)建sqlSession的工廠
sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
沒什么難的,去掉 try-catch,也就兩行代碼。
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
是的,那只是你以為的兩行代碼,其實(shí)......
話不多說,指北君就來給大家揭秘這冰山下面的東西。
2、代碼剖析
根據(jù)上面的時(shí)序圖,我們分析根據(jù)源碼分析每個(gè)步驟。
①、獲取配置文件輸入流
InputStream inputStream = Resources.getResourceAsStream("mybatis.config.xml");
這里沒什么好說的,就是獲取配置文件的輸入流。
②、build(in)
這里的 in 就是上一步獲取的輸入流 inputStream。
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
在進(jìn)入到 build 方法:
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
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.
}
}
}
③、XMLConfigBuilder(in)
這一段代碼是為了解析我們的配置文件,配置文件是 XML形式 ,我在之前的博客介紹過解析 XML 的幾種方式。
一種是基于樹的結(jié)構(gòu)來解析的稱為DOM;另一種是基于事件流的形式稱為SAX和(StAX)
兩者各有優(yōu)缺點(diǎn),我這里不做詳細(xì)說明,想了解的可以看我之前的文章。
而 Mybatis 使用的是 DOM 形式,并結(jié)合 XPath 來解析配置文件。
④、parse()
public Configuration parse() {
if (this.parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
} else {
this.parsed = true;
this.parseConfiguration(this.parser.evalNode("/configuration"));
return this.configuration;
}
}
從 /configuration 標(biāo)簽處開始解析。然后我們進(jìn)入到 this.parseConfiguration() 方法中:
private void parseConfiguration(XNode root) {
try {
this.propertiesElement(root.evalNode("properties"));
Properties settings = this.settingsAsProperties(root.evalNode("settings"));
this.loadCustomVfs(settings);
this.loadCustomLogImpl(settings);
this.typeAliasesElement(root.evalNode("typeAliases"));
this.pluginElement(root.evalNode("plugins"));
this.objectFactoryElement(root.evalNode("objectFactory"));
this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
this.reflectorFactoryElement(root.evalNode("reflectorFactory"));
this.settingsElement(settings);
this.environmentsElement(root.evalNode("environments"));
this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
this.typeHandlerElement(root.evalNode("typeHandlers"));
this.mapperElement(root.evalNode("mappers"));
} catch (Exception var3) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
}
}
看到這是不是很熟悉了,這不就是mybatis-config.xml 配置文件里面的各個(gè)標(biāo)簽名嘛,是的,這就是解析該文件,然后全部放在 configuration 對(duì)象中。需要注意的是,這里的 configuration 對(duì)象不僅包括 mybatis-config.xml 文件內(nèi)容,也包括 xxxMapper.xml 文件內(nèi)容。
⑤、build(configuration)
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
就是去 new 了一個(gè) DefaultSqlSessionFactory 對(duì)象,將 configuration 作為參數(shù)。
⑥、DefaultSqlSessionFactory(configuration)
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
3、總結(jié)
自此,SqlSessionFactory 的創(chuàng)建過程就講完了,總的來說就是一個(gè)封裝了配置文件的工廠類。那么得到了 SqlSessionFactory 這個(gè)工廠對(duì)象,接下來干嘛?生產(chǎn) SqlSession,然后通過 SqlSession 進(jìn)行數(shù)據(jù)庫的增刪改查操作
-
SQL
+關(guān)注
關(guān)注
1文章
762瀏覽量
44117 -
代碼
+關(guān)注
關(guān)注
30文章
4779瀏覽量
68525 -
factory
+關(guān)注
關(guān)注
0文章
4瀏覽量
1901 -
mybatis
+關(guān)注
關(guān)注
0文章
60瀏覽量
6709
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論