MyBatis框架的启动前期需要加载相关的XML配置信息。从官网上我们可以了解到他具有十几个节点。其中笔者认为比较重要的节点是settings节点、properties节点、environments节点、 transactionManager节点。至于相关的作用到官网看过一篇都会明白。

MyBatis框架的XML配置到底有几个节点,这个必须去查看一下相关的DTD文件才行。DTA文件就在包名为org.apache.ibatis.builder.xml的下面。由于显示的问题笔者只复制出部分来。

<?xml version="1.0" encoding="UTF-8" ?>

<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>

<!ELEMENT databaseIdProvider (property*)>
<!ATTLIST databaseIdProvider
type CDATA #REQUIRED
>

从上面我们就可以看到根节点就是configuration。同时我们也能找到上面笔者提到的比较重要的几个节点。

1.properties 节点:可以把它理解为变量吧。事实上他可以是一个properties文件。
2.settings 节点:MyBatis框架有一些内部需要设置的配置信息。请查看官网对于settings的介绍。
3.typeAliases 节点:设置相应的别名。这样子可以简少重复的编写。
4.typeHandlers 节点:官网叫为类型处理器,大部用于结果集应射到对象的时候需要。
5.environments 节点:这个节点按道理来讲是大家最清楚的。因为设置数据连接的信息就在这里。
6.mappers 节点:对象模型与数据表映射的信息。
注意:笔者这里只是写出可能常用的。

知道了上面的信息之后,在去看对应的源码你就会发现很简单——大部分都是一一对应的。 来,让我们从上一章中讲到的切入口类(SqlSessionFactoryBuilder)的build方法查看进去。SqlSessionFactoryBuilder类里面重载了很多build的方法。但是所有的方法最后都会流入下面的方法中去。

 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.
}
}
}

从上面的代码中我们可以看到这个方法有三个参数:

1.Reader reader:XML配置所在的文件流。

2.String environment:指定要执行的环境ID。

3.Properties properties:加载的变理信息。

XMLConfigBuilder类的作用就是用于加载XML配置文件,也可以理解为读取。他的parse方法充分的体现出他的作用来。

  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 {
Properties settings = settingsAsPropertiess(root.evalNode("settings"));
//issue #117 read properties first
propertiesElement(root.evalNode("properties"));
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);
}
}

从要上面的俩个方法中我们可以看到很眼熟的代码字眼。相信不难看出就是加载各个节点上的信息。事实上如果我们查看一下parse方法的返回类型我们就可以知道这个步骤最后就是为了生成相应的Configuration类实例。可以这样子讲有关配置信息加载最后一定都在Configuration类实例里面。所以查看Configuration类就变得很有意义。源码笔者就不贴出来占地方。

XMLConfigBuilder类源码里面有俩个地方是笔者比较喜欢的。一个是简单封装了读取XML的操作类——XPathParser类。可能对于JAVA来讲这不算什么。笔者从事过C#开发,所以感觉比较深吧。他只是做了一个简单的封装。可是笔者看起来在读取XML便得更加载顺心了——可读性更强了。

 public String evalString(Object root, String expression) {
String result = (String) evaluate(expression, root, XPathConstants.STRING);
result = PropertyParser.parse(result, variables);
return result;
} public Boolean evalBoolean(String expression) {
return evalBoolean(document, expression);
} public Boolean evalBoolean(Object root, String expression) {
return (Boolean) evaluate(expression, root, XPathConstants.BOOLEAN);
} public Short evalShort(String expression) {
return evalShort(document, expression);
}

上面是XPathParser类读取XML文件值各自需要调用的方法。我们可以清楚的可以知道返回类型和调用的节点。笔者认为简单一小步,可是明理一大步。XMLConfigBuilder类源码里面还有一个笔者认为需要去注意学习的地方——MetaClass类。他的功能跟反射有关系,同时用到ReflectorFactory类和Reflector类。他这样子封装之后用到反射功能便得更加的容易理解和可观。过多的介绍还不如自己亲自去看一下体验一下。

好了,现在让我们回过头在来看看build方法最后返回什么才是最重要的。从源码中我们知道他返回的是一个DefaultSqlSessionFactory类型。

public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}

本章的重点类出来了。当程序执行到上面的方法的时候,说明加载配置信息的工作已经结束了。一个新的工作又要开始了。让我们在看一下笔者的例子代码吧。

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
IProductMapper dao = session.getMapper(IProductMapper.class);

笔者调用的没有参数的openSession方法。从这个方法里我们可以看到他又去调用了一个叫openSessionFromDataSource的方法。这个方法才是结果和开始的连接点。

  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}

上面的方法中有几个比较重要的类:Executor类、DefaultSqlSession类。其中特别是Executor类。本章就不明讲。后面会讲到。我们可以看到最后返回类是DefaultSqlSession类。对于数据库的增删改查就依赖这个类。

显然文章到了这里就已经把接下来要去了解工作做了一个明确的方法——了解Executor类的功能。这样子我们就可以进一步的了解框架了。

MyBatis 源码分析——配置信息的更多相关文章

  1. MyBatis源码分析-MyBatis初始化流程

    MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...

  2. MyBatis源码分析-SQL语句执行的完整流程

    MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...

  3. MyBatis源码分析(5)——内置DataSource实现

    @(MyBatis)[DataSource] MyBatis源码分析(5)--内置DataSource实现 MyBatis内置了两个DataSource的实现:UnpooledDataSource,该 ...

  4. MyBatis源码分析(2)—— Plugin原理

    @(MyBatis)[Plugin] MyBatis源码分析--Plugin原理 Plugin原理 Plugin的实现采用了Java的动态代理,应用了责任链设计模式 InterceptorChain ...

  5. 【MyBatis源码分析】select源码分析及小结

    示例代码 之前的文章说过,对于MyBatis来说insert.update.delete是一组的,因为对于MyBatis来说它们都是update:select是一组的,因为对于MyBatis来说它就是 ...

  6. MyBatis源码分析之环境准备篇

    前言 之前一段时间写了[Spring源码分析]系列的文章,感觉对Spring的原理及使用各方面都掌握了不少,趁热打铁,开始下一个系列的文章[MyBatis源码分析],在[MyBatis源码分析]文章的 ...

  7. Mybatis源码分析-StatementHandler

    承接前文Mybatis源码分析-BaseExecutor,本文则对通过StatementHandler接口完成数据库的CRUD操作作简单的分析 StatementHandler#接口列表 //获取St ...

  8. mybatis源码分析(一)

    mybatis源码分析(sqlSessionFactory生成过程) 1. mybatis框架在现在各个IT公司的使用不用多说,这几天看了mybatis的一些源码,赶紧做个笔记. 2. 看源码从一个d ...

  9. 【MyBatis源码分析】环境准备

    前言 之前一段时间写了[Spring源码分析]系列的文章,感觉对Spring的原理及使用各方面都掌握了不少,趁热打铁,开始下一个系列的文章[MyBatis源码分析],在[MyBatis源码分析]文章的 ...

随机推荐

  1. JavaEE笔记(十二)

    代理的三种配置 beans配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=& ...

  2. debian系统下改语言设置

    debian系统下改语言设置 安装debian 的时候选择了中文zh_CN_UTF-8,然后进系统后想换成en_US_UTF-8 可以使用一下命令选择:找到需要的语言 确定即可 dpkg-reconf ...

  3. Linux下的openvpn配置 与 easy-rsa3的证书生成

    #注意:以下操作由服务端操作即可#PS:为什么我找不到var文件??============安装===============wget -O /etc/yum.repos.d/epel.repo ht ...

  4. Kubernetes学习之路(十九)之Kubernetes dashboard认证访问

    Dashboard:https://github.com/kubernetes/dashboard 一.Dashboard部署 由于需要用到k8s.gcr.io/kubernetes-dashboar ...

  5. R实战 第六篇:数据变换(aggregate+dplyr)

    数据分析的工作,80%的时间耗费在处理数据上,而数据处理的主要过程可以分为:分离-操作-结合(Split-Apply-Combine),也就是说,首先,把数据根据特定的字段分组,每个分组都是独立的:然 ...

  6. javascript典型bug——错误的闭包

    昨天QT给我的一个功能提了一个bug.大概意思就是说,一段在不同位置都会被调用的代码,在A处被调用的时候,似乎会对其他调用的地方产生影响. 我仔细debug了半天,终于找到了原因.简化过的代码如下: ...

  7. git 跟踪提交记录

    一.克隆git仓库 git clone ssh://hwl@xxx/home/data/repositories/git.git 二.申明使用人信息,以便跟踪提交记录 $ git config --g ...

  8. UE4官方行为树快速入门文档解析和修改

    近学习了UE4官方文档的行为树快速入门指南,发现里面的部分逻辑稍稍有点混乱和重叠,于是加入了自己的想法,修改了部分行为树逻辑,优化了其AI寻路能力. 初始的基本操作和资源创建同官方文档一样:1个Fol ...

  9. hyperledger-fabirc1.2-ca-server的生产示例

    hyperledger-fabirc1.2-ca-server的生产示例,带TLS 在fabirc-samples/first-network中启动网络,其ca证书是利用crypto的工具生成的,但是 ...

  10. 第二十次ScrumMeeting博客

    第二十次ScrumMeeting博客 本次会议于12月11日(一)22时整在3公寓725房间召开,持续20分钟. 与会人员:刘畅.辛德泰.张安澜.赵奕.方科栋. 1. 每个人的工作(有Issue的内容 ...