文章目录
引子
private static SqlSessionFactory getSessionFactory() {
SqlSessionFactory sessionFactory = null;
String resource = "mybatis-config.xml";
try {
SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
Reader reader=Resources.getResourceAsReader(resource);
//1 看一下这个SqlSessionFactoryBuilder怎么根据流来创建SqlSessionFactory的
sessionFactory = sqlSessionFactoryBuilder.build(reader);
} catch (IOException e) {
e.printStackTrace();
}
return sessionFactory;
}
SqlSessionFactoryBuilder
看一下这个SqlSessionFactoryBuilder怎么根据流来创建SqlSessionFactory的???
public SqlSessionFactory build(Reader reader) {
//2 调用下面的重载方法
return this.build((Reader)reader, (String)null, (Properties)null);
}
//3
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
SqlSessionFactory var5;
try {
//parser可以理解为一个文件解析建建造者
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
var5 = this.build(parser.parse());//4 parser.parse()看下头的源码,重点是返回一个Configuration!!!然后调用了build(Configuration)方法。
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException var13) {
;
}
}
return var5;
}
XMLConfigBuilder
创建一个由configuration.xml定制(或者说解析)的Configuration对象!
//5
public Configuration parse() {
if (this.parsed) {//如果已经被解析过
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
} else {//如果还没被解析过
this.parsed = true;
//注意到根节点就叫configuration.
this.parseConfiguration(this.parser.evalNode("/configuration"));//6 看下面parseConfiguration(XNode root)
return this.configuration;
}
}
//这个方法暂时不用懂,知道是解析就行,回过头看一下类结构图,就可以知道这个XMLConfigBuilder就是来创建一个Configuration对象的,这个对象调用parse。
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的配置文件中:
- configuration节点为根节点。
- 在configuration节点之下,我们可以配置10个子节点, 分别为:properties、typeAliases、plugins、objectFactory、objectWrapperFactory、settings、environments、databaseIdProvider、typeHandlers、mappers。
SqlSessionFactoryBuiler
//7
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
DefaultSqlSessionFactoryBuilder
它实现了SqlSessionFactory接口,表面它就是一个SqlSessionFactory。
注意到他有一个Configuration类型的configuration属性,有一个构造方法也是依据它来创建一个SqlSessionFactory.
SqlSessionFactory只有两类方法,一类是openSession(),一类是getConfiguration()-----这是因为Configuration的来源configuration.xml包含了对于session的配置.