前言

对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外。本章将通过以下几点详细介绍MyBatis的初始化过程。

  1. MyBatis的初始化做了什么
  2. MyBatis基于XML配置文件创建Configuration对象的过程
  3. 手动加载XML配置文件创建Configuration对象完成初始化,创建并使用SqlSessionFactory对象
  4. 涉及到的设计模式

一、 MyBatis的初始化做了什么

任何框架的初始化,无非是加载自己运行时所需要的配置信息。MyBatis的配置信息,大概包含以下信息,其高层级结构如下:

× configuration 配置

× properties 属性

× settings 设置

× typeAliases 类型命名

× typeHandlers 类型处理器

× objectFactory 对象工厂

× plugins 插件

× environments 环境

× environment 环境变量

× transactionManager 事务管理器

× dataSource 数据源

×映射器

MyBatis的上述配置信息会配置在XML配置文件中,那么,这些信息被加载进入MyBatis内部,MyBatis是怎样维护的呢?

MyBatis采用了一个非常直白和简单的方式---使用 org.apache.ibatis.session.Configuration 对象作为一个所有配置信息的容器,Configuration对象的组织结构和XML配置文件的组织结构几乎完全一样(当然,Configuration对象的功能并不限于此,它还负责创建一些MyBatis内部使用的对象,如Executor等,这将在后续的文章中讨论)。如下图所示:

 

MyBatis根据初始化好Configuration信息,这时候用户就可以使用MyBatis进行数据库操作了。

可以这么说,MyBatis初始化的过程,就是创建 Configuration对象的过程。

MyBatis的初始化可以有两种方式:

  • 基于XML配置文件:基于XML配置文件的方式是将MyBatis的所有配置信息放在XML文件中,MyBatis通过加载并XML配置文件,将配置文信息组装成内部的Configuration对象
  • 基于Java API:这种方式不使用XML配置文件,需要MyBatis使用者在Java代码中,手动创建Configuration对象,然后将配置参数set 进入Configuration对象中

(PS: MyBatis具体配置信息有哪些,又分别表示什么意思,不在本文的叙述范围)

接下来我们将通过 基于XML配置文件方式的MyBatis初始化,深入探讨MyBatis是如何通过配置文件构建Configuration对象,并使用它的。

二、MyBatis基于XML配置文件创建Configuration对象的过程

现在就从使用MyBatis的简单例子入手,深入分析一下MyBatis是怎样完成初始化的,都初始化了什么。看以下代码:

 

有过MyBatis使用经验的读者会知道,上述语句的作用是执行com.foo.bean.BlogMapper.queryAllBlogInfo 定义的SQL语句,返回一个List结果集。总的来说,上述代码经历了mybatis初始化 -->创建SqlSession -->执行SQL语句 返回结果三个过程。

上述代码的功能是根据配置文件mybatis-config.xml 配置文件,创建SqlSessionFactory对象,然后产生SqlSession,执行SQL语句。而mybatis的初始化就发生在第三句:SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

现在就让我们看看第三句到底发生了什么。

MyBatis初始化基本过程:

SqlSessionFactoryBuilder根据传入的数据流生成Configuration对象,然后根据Configuration对象创建默认的SqlSessionFactory实例。

初始化的基本过程如下序列图所示:

 

由上图所示,mybatis初始化要经过简单的以下几步:

1. 调用SqlSessionFactoryBuilder对象的build(inputStream)方法;

2. SqlSessionFactoryBuilder会根据输入流inputStream等信息创建XMLConfigBuilder对象;

3. SqlSessionFactoryBuilder调用XMLConfigBuilder对象的parse()方法;

4. XMLConfigBuilder对象返回Configuration对象;

5. SqlSessionFactoryBuilder根据Configuration对象创建一个DefaultSessionFactory对象;

6. SqlSessionFactoryBuilder返回 DefaultSessionFactory对象给Client,供Client使用。

SqlSessionFactoryBuilder相关的代码如下所示:

 
 

 
 

上述的初始化过程中,涉及到了以下几个对象:

  • SqlSessionFactoryBuilder : SqlSessionFactory的构造器,用于创建SqlSessionFactory,采用了Builder设计模式
  • Configuration :该对象是mybatis-config.xml文件中所有mybatis配置信息
  • SqlSessionFactory:SqlSession工厂类,以工厂形式创建SqlSession对象,采用了Factory工厂设计模式
  • XmlConfigParser :负责将mybatis-config.xml配置文件解析成Configuration对象,共SqlSessonFactoryBuilder使用,创建SqlSessionFactory

创建Configuration对象的过程

接着上述的 MyBatis初始化基本过程讨论,当SqlSessionFactoryBuilder执行build()方法,调用了XMLConfigBuilder的parse()方法,然后返回了Configuration对象。那么parse()方法是如何处理XML文件,生成Configuration对象的呢?

1. XMLConfigBuilder会将XML配置文件的信息转换为Document对象,而XML配置定义文件DTD转换成XMLMapperEntityResolver对象,然后将二者封装到XpathParser对象中,XpathParser的作用是提供根据Xpath表达式获取基本的DOM节点Node信息的操作。如下图所示:

 

 

2. 之后XMLConfigBuilder调用parse()方法:会从XPathParser中取出 <configuration>节点对应的Node对象,然后解析此Node节点的子Node:

properties, settings, typeAliases,typeHandlers, objectFactory, objectWrapperFactory, plugins, environments,databaseIdProvider, mappers

 
 

 

注意:在上述代码中,还有一个非常重要的地方,就是解析XML配置文件子节点<mappers>的方法mapperElements(root.evalNode("mappers")), 它将解析我们配置的Mapper.xml配置文件,Mapper配置文件可以说是MyBatis的核心,MyBatis的特性和理念都体现在此Mapper的配置和设计上,我们将在后续的文章中讨论它,敬请期待~

3. 然后将这些值解析出来设置到Configuration对象中。

解析子节点的过程这里就不一一介绍了,用户可以参照MyBatis源码仔细揣摩,我们就看上述的environmentsElement(root.evalNode("environments")); 方法是如何将environments的信息解析出来,设置到Configuration对象中的:

 
 

 

4. 返回Configuration对象

我们将上述的MyBatis初始化基本过程的序列图细化。

 

三、手动加载XML配置文件创建Configuration对象完成初始化,创建并使用SqlSessionFactory对象

我们可以使用XMLConfigBuilder手动解析XML配置文件来创建Configuration对象,代码如下:

 
四、涉及到的设计模式

初始化的过程涉及到创建各种对象,所以会使用一些创建型的设计模式。在初始化的过程中,Builder模式运用的比较多。

Builder模式应用1: SqlSessionFactory的创建

对于创建SqlSessionFactory时,会根据情况提供不同的参数,其参数组合可以有以下几种:

 

由于构造时参数不定,可以为其创建一个构造器Builder,将SqlSessionFactory的构建过程和表示分开:

 
MyBatis将SqlSessionFactoryBuilder和SqlSessionFactory相互独立。

Builder模式应用2: 数据库连接环境Environment对象的创建

在构建Configuration对象的过程中,XMLConfigParser解析 mybatis XML配置文件节点<environment>节点时,会有以下相应的代码:

 

在Environment内部,定义了静态内部Builder类:

 
 

 

 

以上就是本文 《深入理解mybatis原理》Mybatis初始化机制详解的全部内容,希望对大家有所帮助!上述内容如有不妥之处,还请读者指出,共同探讨,共同进步!

如何完美回答面试官问的Mybatis初始化原理!!!的更多相关文章

  1. 面试官问你MyBatis SQL是如何执行的?把这篇文章甩给他

    初识 MyBatis MyBatis 是第一个支持自定义 SQL.存储过程和高级映射的类持久框架.MyBatis 消除了大部分 JDBC 的样板代码.手动设置参数以及检索结果.MyBatis 能够支持 ...

  2. 面试官问:Mybatis中的TypeHandler你用过吗?

    持续原创输出,点击上方蓝字关注我吧 目录 前言 环境配置 什么是TypeHandler? 如何自定义? 如何将其添加到Mybatis中? XML文件中如何指定TypeHandler? 源码中如何执行T ...

  3. 看完这一篇,再也不怕面试官问到IntentService的原理

    IntentService是什么 在内部封装了 Handler.消息队列的一个Service子类,适合在后台执行一系列串行依次执行的耗时异步任务,方便了我们的日常coding(普通的Service则是 ...

  4. 每日一问:面试结束时面试官问"你有什么问题需要问我呢",该如何回答?

    面试结束时面试官问"你有什么问题需要问我呢",该如何回答?

  5. 美女面试官问我Python如何优雅的创建临时文件,我的回答....

    [摘要] 本故事纯属虚构,如有巧合,他们故事里的美女面试官也肯定没有我的美,请自行脑补... 小P像多数Python自学者一样,苦心钻研小半年,一朝出师投简历. 这不,一家招聘初级Python开发工程 ...

  6. 【MySQL】面试官问我:MySQL如何实现无数据插入,有数据更新?我是这样回答的!

    写在前面 马上就是金九银十的跳槽黄金期了,很多读者都开始出去面试了.这不,又一名读者出去面试被面试官问了一个MySQL的问题:向MySQL中插入数据,如何实现MySQL中没有当前id标识的数据时插入数 ...

  7. 「每日一题」有人上次在dy面试,面试官问我:vue数据绑定的实现原理。你说我该如何回答?

    关注「松宝写代码」,精选好文,每日一题 ​时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 来源:原创 一.前言 文章首发在「松宝写代码」 2020. ...

  8. 当面试官问我ArrayList和LinkedList哪个更占空间时,我这么答让他眼前一亮

    前言 今天介绍一下Java的两个集合类,ArrayList和LinkedList,这两个集合的知识点几乎可以说面试必问的. 对于这两个集合类,相信大家都不陌生,ArrayList可以说是日常开发中用的 ...

  9. 漂亮回答面试官struts2的原理

    众所周知,Struts2是个非常优秀的开源框架,我们能用Struts2框架进行开发,同时能快速搭建好一个Struts2框架,但我们是否能把Struts2框架的工作原理用语言表达清楚,你表达的原理不需要 ...

随机推荐

  1. Javascript面试题收集

    第一部分“ 来源: http://bbs.miaov.com/forum.php?mod=viewthread&tid=6974 1.var a = b = 1; ——这样定义变量的隐患 fu ...

  2. Spark SQL例子

    综合案例分析 现有数据集 department.json与employee.json,以部门名称和员工性别为粒度,试计算每个部门分性别平均年龄与平均薪资. department.json如下: {&q ...

  3. 手工搭建web项目

    https://www.cnblogs.com/skyblue-li/p/5966311.html

  4. Jenkins之定时任务

    H的用法: H 10 * * *  ,这里H不是小时的意思,符号H(代表“Hash”,后面用“散列”代替) 符号H 在一定范围内可被认为是一个随机值,但实际上它是任务名称的一个散列而不是随机函数,每个 ...

  5. poj 2349 求最小生成树里面第m长的边

    题目链接:https://vjudge.net/problem/POJ-2349 题意: 题目就是要我们找到一个最小的值D,把图里面所有大于D的边去掉之后剩余的连通分支的数量为S.这个就是找这个图里面 ...

  6. 【转】GT 的性能测试方案解析

    前言 本文将整理腾讯GT各个性能测试项的测试方法,目的是为了帮助移动性能专项测试同学快速过一遍腾讯GT各个性能数据是如何获取的.另外对腾讯GT还不了解或者不知道它能做什么的同学可以看看这篇文章:htt ...

  7. Python基础-python数据类型之集合(四)

    集合 集合是一个无序的,不重复的数据组合,基本功能包括关系测试和消除重复元素. 集合对象还支持 union,intersection,difference和 sysmmetric difference ...

  8. 什么是XML?

    XML被设计用来传输和存储数据. HTML被设计用来显示数据. 什么是XML? XML指可扩展标记语言(EXtensible Markup Language) XML是一种标记语言,很类似HTML X ...

  9. Extension-valuepart

    data: ls_extension type bapiparex. loop at extensionin into ls_extension . read table extensionout i ...

  10. .Net 获取日期所属于一年中的第几周

    关键代码: public static int WeekOfYear(DateTime dt, CultureInfo ci) { //强制设置周一是每周的第一天 return ci.Calendar ...