MyBatis框架的使用及源码分析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder
在 <MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用> 的demo中看到了SessionFactory的创建过程:
SqlSessionFactory sessionFactory = null;
String resource = "mybatisConfig.xml";
try {
sessionFactory = new SqlSessionFactoryBuilder().build(Resources
.getResourceAsReader(resource));
} catch (IOException e) {
e.printStackTrace();
}
那么我们就从SqlSessionFactoryBuilder开始,看看Mybatis的加载过程。
SqlSessionFactoryBuilder的核心源码:
package org.apache.ibatis.session;
public class SqlSessionFactoryBuilder {
//通过Reader读取Mybatis配置
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse()); //parse()方法得到Configuration
} 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.
}
}
}
//通过InputStream读取Mybatis配置
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse()); //parse()方法得到Configuration
} 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.
}
}
}
//以上2个方法最终调用的是build(Configuration config)
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
通过源码,我们可以看到SqlSessionFactoryBuilder 通过XMLConfigBuilder 去解析我们传入的mybatis的配置文件,构造出Configuration,最终返回new DefaultSqlSessionFactory(config)的SqlSessionFactory实例。
接下来我们看看 XMLConfigBuilder 是怎样解析Mybatis的配置文件的,下面是部分源码:
package org.apache.ibatis.builder.xml; /**
* 解析Mybatis配置文件
*/
public class XMLConfigBuilder extends BaseBuilder { private boolean parsed;
private XPathParser parser;
private String environment; public XMLConfigBuilder(Reader reader) {
this(reader, null, null);
} public XMLConfigBuilder(Reader reader, String environment) {
this(reader, environment, null);
} public XMLConfigBuilder(Reader reader, String environment, Properties props) {
this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
} public XMLConfigBuilder(InputStream inputStream) {
this(inputStream, null, null);
} public XMLConfigBuilder(InputStream inputStream, String environment) {
this(inputStream, environment, null);
} 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;
} //调用此方法对mybatis配置文件进行解析,返回Configuration对象
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
//从根节点configuration,开始解析
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
} //解析configuration节点下的10个子节点。
private void parseConfiguration(XNode root) {
try {
//解析子节点properties
propertiesElement(root.evalNode("properties")); //issue #117 read properties first
//解析子节点typeAliases 别名
typeAliasesElement(root.evalNode("typeAliases"));
//解析子节点plugins 插件
pluginElement(root.evalNode("plugins"));
//解析子节点objectFactory mybatis为结果创建对象时都会用到objectFactory
objectFactoryElement(root.evalNode("objectFactory"));
//解析子节点objectWrapperFactory
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
//解析settings定义一些全局性的配置
settingsElement(root.evalNode("settings"));
//解析environments 可以配置多个运行环境,但是每个SqlSessionFactory 实例只能选择一个运行环境
environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631
//解析databaseIdProvider MyBatis能够执行不同的语句取决于你提供的数据库供应商。许多数据库供应商的支持是基于databaseId映射
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
//解析typeHandlers 当MyBatis设置参数到PreparedStatement 或者从ResultSet 结果集中取得值时,就会使用TypeHandler 来处理数据库类型与java 类型之间转换
typeHandlerElement(root.evalNode("typeHandlers"));
//解析mappers 主要的crud操作都是在mappers中定义的
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
} }
从上面可以看出可以配置10个子节点, 分别为:properties、typeAliases、plugins、objectFactory、objectWrapperFactory、settings、environments、databaseIdProvider、typeHandlers、mappers。
MyBatis框架的使用及源码分析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder的更多相关文章
- MyBatis框架的使用及源码分析(三) 配置篇 Configuration
从上文<MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder> 我们知道XMLConf ...
- MyBatis框架的使用及源码分析(一) 配置与使用
我们先来看一个例子,简单的了解一下mybatis的mapper接口方式的使用. package org.mybatis.spring.sample; import org.apache.ibatis. ...
- MyBatis框架的使用及源码分析(十一) StatementHandler
我们回忆一下<MyBatis框架的使用及源码分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor> , 这4个Ex ...
- MyBatis框架的使用及源码分析(九) Executor
从<MyBatis框架的使用及源码分析(八) MapperMethod>文中我们知道执行Mapper的每一个接口方法,最后调用的是MapperMethod.execute方法.而当执行Ma ...
- MyBatis框架的使用及源码分析(四) 解析Mapper接口映射xml文件
在<MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder> 一文中,我们知道mybat ...
- Vue.js 源码分析(二) 基础篇 全局配置
Vue.config是一个对象,包含Vue的全局配置,可以在启动应用之前修改下列属性,如下: ptionMergeStrategies ;自定义合并策略的选项silent ...
- MyBatis框架的使用及源码分析(八) MapperMethod
从 <MyBatis框架中Mapper映射配置的使用及原理解析(七) MapperProxy,MapperProxyFactory> 文中,我们知道Mapper,通过MapperProxy ...
- MyBatis框架的使用及源码分析(六) MapperRegistry
我们先Mapper接口的调用方式,见<MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用>的示例: public void findUserById() { Sql ...
- MyBatis框架的使用及源码分析(五) DefaultSqlSessionFactory和DefaultSqlSession
我们回顾<MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用> 一文的示例 private static SqlSessionFactory getSessionF ...
随机推荐
- Python中的Comprehensions和Generations
Python中的Comprehensions和Generations语法都是用来迭代的.Comprehensions语法可用于list,set,dictionary上,而Generations语法分为 ...
- LintCode-374.螺旋矩阵
螺旋矩阵 给定一个包含 m x n 个要素的矩阵,(m 行, n 列),按照螺旋顺序,返回该矩阵中的所有要素. 样例 给定如下矩阵: [ [ 1, 2, 3 ], [ 4, 5, 6 ...
- iOS-【UIDynamic-UIKit动力学】
如果看不到图片 可以尝试更换浏览器(推荐Safari ) 0.了解 •Dynamic Animator:动画者,为动力学元素提供物理学相关的能力及动画,同时为这些元素提供相关的上下文,是动力学元素与底 ...
- centOS 6.5命令方式配置静态IP
想自己做个centOS玩一下,然后通过FTP访问操作,首先查看是否开启了SSH,命令如下: rpm -qa | grep ssh 这个时候看到的是centOS的ssh已经打开!要是通过FTP工具访问还 ...
- 通过设置窗体的AcceptButton属性,可以设置窗体的“接受”按钮,若此设计,则用户每次按下Enter键都相当于单击该按钮
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- OSI参考模型和TCP/IP参考模型
- React 16.x & Hooks
React 16.x & Hooks Hooks https://reactjs.org/docs/hooks-intro.html https://reactjs.org/docs/hook ...
- HUAS 1482 lsy的后宫(DP+矩阵快速幂)
这道题的DP是很好想的,令dp[i][j]表示第i个位置摆第j种妹子的方法数,j为0表示不摆妹子的方法数. dp[i][j]=sigma(dp[i-1][k])(s[j][k]!='1').容易看出这 ...
- bzoj3546[ONTAK2010]Life of the Party
题意是裸的二分图关键点(必然在二分图最大匹配中出现的点).比较经典的做法在cyb15年的论文里有: 前几天写jzoj5007的时候脑补了一种基于最小割可行边的做法:考虑用最大流求解二分图匹配.如果某个 ...
- Django 2.0 学习(09):Django 静态文件(样式和背景图片)
应用的定制化:静态文件 首先,在polls目录中创建一个名叫static的目录.Django会在该目录里面查找静态文件,类似于Django在polls/template目录下查找模板文件. Djang ...