1,讀取配置文件,生成連接
2,讀取sql語句,生成sql語句——執行,得到結果,組裝到結果集中
1,讀取配置文件,生成連接
String resource = "mybatis.config.xml";
Reader reader = Resources.getResourceAsReader(resource); \\讀取到配置文件,將文件以輸入流的方式讀取到內存中
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);
SqlSession ss = ssf.openSession();
SqlSessionFactoryBuilder類中重載了9個build方法。前4個的配置輸入是 Reader 。後4個的配置輸入是 InputStreatm 。最後一個直接返回默認的連接工廠類。
兩個生成連接工廠的方法寫法幾乎完全一致,通過創建一個XMLConfigBuilder對象,執行其parse()方法得到一個Configuration,把這個Configuration傳入最後一個構造方法生成 連接工廠類
public SqlSessionFactory build(Reader reader) {
return this.build((Reader)reader, (String)null, (Properties)null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return this.build((Reader)reader, environment, (Properties)null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return this.build((Reader)reader, (String)null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
SqlSessionFactory var5;
。。。
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
var5 = this.build(parser.parse());
。。。
return var5;
}
public SqlSessionFactory build(InputStream inputStream) {
return this.build((InputStream)inputStream, (String)null, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return this.build((InputStream)inputStream, environment, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return this.build((InputStream)inputStream, (String)null, properties);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
SqlSessionFactory var5;
。。。
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
var5 = this.build(parser.parse());
。。。
return var5;
}
public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);}
XMLConfigBuilder的作用就是解析mybatis的配置文件,然後根據配置生成連接工廠。
XMLConfigBuilder有以下4個私有屬性
private boolean parsed; //是否解析過
private final XPathParser parser; //配置文件路徑
private String environment; //配置文件裏的環境,沒有指定就使用默認的
private final ReflectorFactory localReflectorFactory;
XMLConfigBuilder中重載了多個構造方法以根據不同參數來構造對象,所有的構造方法都指向了一個私有的構造方法。這裏需要一個XPathParser對象,以及前面傳過來的兩個參數
public XMLConfigBuilder(Reader reader, String environment, Properties props) {
this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
}
public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
}
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
super(new Configuration());
this.localReflectorFactory = new DefaultReflectorFactory(); //反射工廠,用來返回sql中指定的類信息
ErrorContext.instance().resource("SQL Mapper Configuration");
this.configuration.setVariables(props);
this.parsed = false; //默認沒有解析過,解析之後這裏變爲true,只能解析一次
this.environment = environment; //配置文件中的環境
this.parser = parser;
}
parse()方法是比較重要的。首先判斷是否解析過配置,這裏只能解析一次(解析一次就得到了全部信息,貌似就沒必要進行第二次了,浪費資源)。解析配置調用parseConfiguration()方法解析配置文件
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;
}
}
parseConfiguration方法是讀取配置文件保存到類中的核心方法。
在此,將配置配置文件中的各個標籤下的屬性都讀取到類中保存。該類是Configuration的一個實體類,並且是XMLConfigBuilder的一個 protected 的屬性(繼承自BaseBuilder)。得到的這個Configuration最終作爲參數傳入SqlSessionFactoryBuilder的構造方法中,得到連接工廠類
private void parseConfiguration(XNode root) {
try {
this.propertiesElement(root.evalNode("properties"));
Properties settings = this.settingsAsProperties(root.evalNode("settings"));
this.loadCustomVfs(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);
}
}
DefaultSqlSessionFactory類中只有一個構造方法,一堆重載的openSession()方法,而最終指向的有兩個私有方法,這兩個私有方法最終都返回了DefaultSqlSession(實現了SqlSession接口)。Session創建成功
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
//這裏是一堆重載的 openSession 方法
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
DefaultSqlSession var8;
try {
Environment environment = this.configuration.getEnvironment();
TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
Executor executor = this.configuration.newExecutor(tx, execType);
var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
} catch (Exception var12) {
this.closeTransaction(tx);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + var12, var12);
} finally {
ErrorContext.instance().reset();
}
return var8;
}
private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
DefaultSqlSession var8;
try {
boolean autoCommit;
try {
autoCommit = connection.getAutoCommit();
} catch (SQLException var13) {
autoCommit = true;
}
Environment environment = this.configuration.getEnvironment();
TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
Transaction tx = transactionFactory.newTransaction(connection);
Executor executor = this.configuration.newExecutor(tx, execType);
var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error opening session. Cause: " + var14, var14);
} finally {
ErrorContext.instance().reset();
}
return var8;
}
}
第一次寫,權當自己做的筆記吧!