在“Mybatis入門”篇中,以一個簡單的demo,讓我們初步了解MyBatis的運作機制。 官方解釋"每個基于MyBatis的應用都是以一個SqlSessionFactory的執行個體為中心,SqlSessionFactory的執行個體可以通過SqlSessionFactoryBuilder獲得。而SqlSessionFactoryBuilder則可以從XML配置檔案或一個預先定制的configuration的執行個體建構SqlSessionFactory的執行個體" 下面跟蹤源碼檢視建構SqlSessionFactory執行個體的過程。 1、建立SqlSessionFactory對象:
private SqlSessionFactory getSqlSessionFactory(){
String resource = "mybatis-config.xml" ;
SqlSessionFactory sqlSessionFactory = null;
InputStream stream = null;
try {
stream = Resources. getResourceAsStream(resource) ;
sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream) ;
} catch (Exception e){
e.printStackTrace() ;
}
return sqlSessionFactory ;
}
2、首先我們看一下SqlSessionFactoryBuilder()是如何建構SqlSessionFactory對象的。
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(Reader reader) {
return build(reader , null, null) ;
}
public SqlSessionFactory build(Reader reader , String environment) {
return build(reader , environment , null) ;
}
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) ;
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.
}
}
}
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream , null, null) ;
}
public SqlSessionFactory build(InputStream inputStream , String environment) {
return build(inputStream , environment , null) ;
}
public SqlSessionFactory build(InputStream inputStream , Properties properties) {
return build(inputStream , null, properties) ;
}
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.
}
}
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config) ;
}
}
SqlSessionFactoryBuilder對象建立SqlSessionFactory,我主要解釋一下位元組流,字元流可參考位元組流。
3、建立SqlSessionFactory 對象,主要是通過XMLConfigBuilder對象來解析MyBatis配置檔案,下面我們了解一下解析過程。 XMLConfigBuilder類源碼:
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()) ;
ErrorContext. instance().resource( "SQL Mapper Configuration") ;
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;
parseConfiguration( parser.evalNode( "/configuration")) ;
return configuration ;
}
private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
propertiesElement(root.evalNode( "properties")) ;
Properties settings = settingsAsProperties(root.evalNode( "settings")) ;
loadCustomVfs(settings) ;
typeAliasesElement(root.evalNode( "typeAliases")) ;
pluginElement(root.evalNode( "plugins")) ;
objectFactoryElement(root.evalNode( "objectFactory")) ;
objectWrapperFactoryElement(root.evalNode( "objectWrapperFactory")) ;
reflectorFactoryElement(root.evalNode( "reflectorFactory")) ;
settingsElement(settings) ;
environmentsElement(root.evalNode( "environments")) ;
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) ;
}
}
4、通過上面的XMLConfigBuilder 類,建構Configuration對象,最後DefaultSqlSessionFactory(config)建立SqlSessionFactory對象。
public class DefaultSqlSessionFactory implements SqlSessionFactory {
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration ;
}
}
對于如何建立SqlSessionFactory對象,源碼到此結束。 本人初入行不久,望大神們不吝賜教。