上一篇 mybatis源码执行流程
下一篇 批量插入数据
一文中总结了获取sqlSessionFactory对象的步骤:
下面我们通过debug的方法,来看看具体实现:
测试代码如下:
public SqlSessionFactory sqlSessionFactory() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
}
1.创建SqlSessionFactoryBuilder,后调用SqlSessionFactoryBuilder的build(InputStream)方法
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
build方法又重载了下面的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.
}
}
}
这个方法的主要作用,是创建一个xml解析器,让后返回一个DefaultSqlSessionFactory。
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;
}
通过以上代码,可以看出,我们解析xml,实际上用的就是一个解析器:XPathParser。
同时,调用了父类的构造方法 super(new Configuration()),创建了一个Configuration对象,用于保存解析出来的各种属性值
接着看XPathParser的parser.parse()是如何解析我们的配置文件的:
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
parse方法内部调用了parseConfiguration(parser.evalNode("/configuration"))方法。
方法的参数,就是mybaits的配置文件mybatis-config.xml的最外层节点名称
看一下这个方法的具体实现:
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);
// read it after objectFactory and objectWrapperFactory issue #631
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);
}
}
这个方法其实就是按照逐个解析配置文件中的标签。
mark01:重写与重载的区别
方法重载是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量或参数类型不能完全相同
方法重写是存在子父类之间的,子类定义的方法与父类中的方法具有相同的方法名字,相同的参数表和相同的返回类型
注:
(1)子类中不能重写父类中的final方法
(2)子类中必须重写父类中的abstract方法
具体可参照:https://www.cnblogs.com/upcwanghaibo/p/6527354.html
上一篇 mybatis源码执行流程
下一篇 批量插入数据