您的位置:首页 > 其它

深入理解MyBatis——初始化

2018-01-05 17:39 253 查看
我们知道使用MyBatis前是需要初始化的,我们来看一段代码:

String resource = "mybatis.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List list = sqlSession.selectList("edu.zhwei.mapper.sqlId");


上述代码所经历的阶段:

1.读取配置文件并创建SqlSessionFactory

2.获得sqlSession

3.执行查询

而MyBatis的初始化就在阶段1中,更准确的说是在第三行代码,根据配置文件,创建立SqlSessionFactory对象。那就让我们看一看这一行代码究竟发生了什么。

SqlSessionFactoryBuilder

相关源码:

public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
//创建XMLConfigBuilder对象,
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
//parser.parse()方法返回一个Configuration 对象,这里需要说明一下。
//返回SqlSessionFactory
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) {
//根据Configuration对象,返回DefaultSqlSessionFactory
return new DefaultSqlSessionFactory(config);
}


说明:根据传入的inputStream, environment, properties创建XMLConfigBuilder对象,XMLConfigBuilder.parse()用来将inputStream创建成一个Configuration对象,然后在调用build(Configuration config)方法返回DefaultSqlSessionFactory。

那么parse()方法是如何实现的呢?

XMLConfigBuilder类

parse()方法源码:

public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
//parser.evalNode("/configuration")返回一个XNode 对象
//parseConfiguration(XNode)将配置文件中配置的信息解析并设置到Configuration对象中
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}

private void parseConfiguration(XNode root) {
try {
//解析各种类型的节点,如properties、typeAliases、plugins等
propertiesElement(root.evalNode("properties")); //issue #117 read properties first
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
settingsElement(root.evalNode("settings"));
environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631
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);
}
}


说明:parser.evalNode(“/configuration”)返回一个XNode 对象,我们看一下evalNode方法,我们发现XNode是取自XPathParser的。

XPathParser.evalNode源码:

public XNode evalNode(String expression) {
return evalNode(document, expression);
}

public XNode evalNode(Object root, String expression) {
Node node = (Node) evaluate(expression, root, XPathConstants.NODE);
if (node == null) {
return null;
}
return new XNode(this, node, variables);
}


XPathParser类:

public class XPathParser {

//document对象
private Document document;
private boolean validation;
//entityResolver对象
private EntityResolver entityResolver;
private Properties variables;
private XPath xpath;
........
}


我们需要关注一下document对象和entityResolver对象。

document对象:包含了XML配置信息

entityResolver:包含了XML中的DTD信息

因此,XMLConfigBuilder调用parse()方法:会从XPathParser中取出 configuration节点对应的XNode对象,然后解析此XNode节点的子,产生Configration对象。

至此,XMLConfigBuilder的parse()就分析完成了。

重新修改

我们再来看第三行代码

//看这里
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//将第三行代码改为如下三行代码

//第一步创建XMLConfigBuilder
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, null,null);
//第二步:执行parse()得到代表配置文件的Configuration对象
Configuration config = parser.parse();

//根据Configuration创建DefaultSqlSessionFactory2
SqlSessionFactory = new DefaultSqlSessionFactory(config);


MyBatis的初始化就是上述过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: