Mybatis源码学习之整体架构(一)
简述
关于ORM的定义,我们引用了一下百度百科给出的定义,总体来说ORM就是提供给开发人员API,方便操作关系型数据库的,封装了对数据库操作的过程,同时提供对象与数据之间的映射功能,解放了开发人员对访问数据库交互的维护,大大提高工作效率。
我们以传统JDBC编程中的查询操作为例进行说明,其主要步骤如下:
(1)注册数据库驱动类,明确指定数据库URL地址、数据库用户名、密码等连接信息。
(2)通过DriverManager打开数据库连接。
(3)通过数据库连接创建Statement对象。
(4)通过Statement对象执行SQL语句,得到ResultSet对象。
ORM框架的主要功能就是根据映射配置文件,完成数据在对象模型与关系模型之间的映射,同时也屏蔽了上述重复的代码,只暴露简单的API供开发人员使用。
mybatis 整体架构
基础支持层
基础支持层包含整个MyBatis的基础模块,这些模块为核心处理层的功能提供了良好的支撑。
反射模块: MyBatis中专门提供了反射模块,该模块对Java原生的反射进行了良好的封装,提供了更加简洁易用的API,方便上层使调用,并且对反射操作进行了一系列优化,例如缓存了类的元数据,提高了反射操作的性能。
类型转换模块: MyBatis为简化配置文件提供了别名机制,该机制是类型转换模块的主要功能之一。类型转换模块的另一个功能是实现JDBC类型与Java类型之间的转换,该功能在为SQL语句绑定实参以及映射查询结果集时都会涉及。在为SQL语句绑定实参时,会将数据由Java类型转换成JDBC类型;而在映射结果集时,会将数据由JDBC类型转换成Java类型。
日志模块: 无论在开发测试环境中,还是在线上生产环境中,日志在整个系统中的地位都是非常重要的。良好的日志功能可以帮助开发人员和测试人员快速定位Bug代码,也可以帮助运维人员快速定位性能瓶颈等问题。目前的Java世界中存在很多优秀的日志框架,例如Log4j、Log4j2、slf4j等。MyBatis作为一个设计优良的框架,除了提供详细的日志输出信息,还要能够集成多种日志框架,其日志模块的一个主要功能就是集成第三方日志框架。
资源加载模块: 资源加载模块主要是对类加载器进行封装,确定类加载器的使用顺序,并提供了加载类文件以及其他资源文件的功能。
解析器模块: 解析器模块的主要提供了两个功能:一个功能是对XPath进行封装,为MyBatis初始化时解析mybatis-config.xml配置文件以及映射配置文件提供支持;另一个功能是为处理动态SQL语句中的占位符提供支持。
数据源模块: 数据源是实际开发中常用的组件之一。现在开源的数据源都提供了比较丰富的功能,例如,连接池功能、检测连接状态等,选择性能优秀的数据源组件对于提升ORM框架乃至整个应用的性能都是非常重要的。MyBatis自身提供了相应的数据源实现,当然MyBatis也提供了与第三方数据源集成的接口,这些功能都位于数据源模块之中。
事务管理: MyBatis对数据库中的事务进行了抽象,其自身提供了相应的事务接口和简单实现。在很多场景中,MyBatis会与Spring框架集成,并由Spring框架管理事务,
缓存模块: 在优化系统性能时,优化数据库性能是非常重要的一个环节,而添加缓存则是优化数据库时最有效的手段之一。正确、合理地使用缓存可以将一部分数据库请求拦截在缓存这一层。 MyBatis中提供了一级缓存和二级缓存,而这两级缓存都是依赖于基础支持层中的缓存模块实现的。这里需要注意的是,MyBatis中自带的这两级缓存与MyBatis以及整个应用是运行在同一个JVM中的,共享同一块堆内存。如果这两级缓存中的数据量较大,则可能影响系统中其他功能的运行,所以当需要缓存大量数据时,优先考虑使用Redis、Memcache等三方缓存产品。
Binding模块: 在调用SqlSession相应方法执行数据库操作时,需要指定映射文件中定义的SQL节点,如果出现拼写错误,我们只能在运行时才能发现相应的异常。为了尽早发现这种错误,MyBatis通过Binding模块将用户自定义的Mapper接口与映射配置文件关联起来,系统可以通过调用自定义Mapper接口中的方法执行相应的SQL语句完成数据库
操作,从而避免上述问题。
值得注意的是,开发人员无须编写自定义Mapper接口的实现,MyBatis会自动为其创建动态代理对象。在有些场景中,自定义Mapper接口可以完全代替映射配置文件,但有的映射规则和SQL语句的定义还是写在映射配置文件中比较方便,例如动态SQL语句的定义。
核心处理层
在核心处理层中实现了MyBatis的核心处理流程,其中包括MyBatis的初始化以及完成一次数据库操作的涉及的全部流程。
配置解析:
在MyBatis初始化过程中,会加载mybatis-config.xml配置文件、映射配置文件以及Mapper接口中的注解信息,解析后的配置信息会形成相应的对象并保存到Configuration对象中。例如,定义的<resultMap>节点(即ResultSet的映射规则)会被解析成ResultMap对象;定义的<result>节点(即属性映射)会被解析成ResultMapping对象。然后,利用该Configuration对象创建SqlSessionFactory对象。待MyBatis初始化之后,开发人员可以通过初始化得到SqlSessionFactory创建SqlSession对象并完成数据库操作。
SQL解析与scripting模块
MyBatis实现动态拼接SQL语句的功能,提供了多种动态SQL语句对应的节点,例如,<where>节点、<if>节点、<foreach>节点等。通过这些节点的组合使用,开发人员可以写出几乎满足所有需求的动态SQL语句。 MyBatis中的scripting模块会根据用户传入的实参,解析映射文件中定义的动态SQL节点,并形成数据库可执行的SQL语句。之后会处理SQL语句中的占位符,绑定用户传入的实参。
SQL执行
SQL语句的执行涉及多个组件,其中比较重要的是Executor、StatementHandler、ParameterHandler和ResultSetHandler。Executor主要负责维护一级缓存和二级缓存,并提供事务管理的相关操作,它会将数据库相关操作委托给StatementHandler完成。StatementHandler首先通过ParameterHandler完成SQL语句的实参绑定,然后通过java.sql.Statement对象执行SQL语句并得到结果集,最后通过ResultSetHandler完成结果集的映射,得到结果对象并返回。
插件
Mybatis自身的功能虽然强大,但是并不能完美切合所有的应用场景,因此MyBatis提供了插件接口,我们可以通过添加用户自定义插件的方式对
MyBatis进行扩展。用户自定义插件也可以改变Mybatis的默认行为,例如,我们可以拦截SQL语句并对其进行重写。由于用户自定义插件会影响MyBatis的核心行为,在使用自定义插件之前,需要了解MyBatis内部的原理,这样才能编写出安全、高效的插件。
接口层
接口层相对简单,其核心是SqlSession接口,该接口中定义了MyBatis暴露给应用程序调用的API,也就是上层应用与MyBatis交互的桥梁。接口层在接收到调用请求时,会调用核心处理层的相应模块来完成具体的数据库操作。
接下来本人对mybatis源码的学习也会围绕其整体架构的模块,由浅入深的学习其思想及编码风格,希望通过对mybatis源码的学习打开自己对常用开源框架源码持续学习的大门,希望自己能一直将源码学习坚持下去,多学习成熟开源框架的设计思想,编码风格,从中汲取丰富的知识,进一步提高本人的编程思想及编码能力。
参考资料:
Mybatis源码学习之整体架构(一)的更多相关文章
- spring源码学习——spring整体架构和设计理念
Spring是在Rod Johnson的<Expert One-On-One J2EE Development and Design >的基础上衍生而来的.主要目的是通过使用基本的java ...
- 【Mybatis源码解析】- 整体架构及原理
整体架构 version-3.5.5 在深入了解Mybatis的源码之前,我们先了解一下Mybatis的整体架构和工作原理,这样有助于我们在阅读源码过程中了解思路和流程. 核心流程 在上一遍的入门程序 ...
- mybatis源码学习(一) 原生mybatis源码学习
最近这一周,主要在学习mybatis相关的源码,所以记录一下吧,算是一点学习心得 个人觉得,mybatis的源码,大致可以分为两部分,一是原生的mybatis,二是和spring整合之后的mybati ...
- mybatis源码学习:一级缓存和二级缓存分析
目录 零.一级缓存和二级缓存的流程 一级缓存总结 二级缓存总结 一.缓存接口Cache及其实现类 二.cache标签解析源码 三.CacheKey缓存项的key 四.二级缓存TransactionCa ...
- mybatis源码学习:基于动态代理实现查询全过程
前文传送门: mybatis源码学习:从SqlSessionFactory到代理对象的生成 mybatis源码学习:一级缓存和二级缓存分析 下面这条语句,将会调用代理对象的方法,并执行查询过程,我们一 ...
- mybatis源码学习:插件定义+执行流程责任链
目录 一.自定义插件流程 二.测试插件 三.源码分析 1.inteceptor在Configuration中的注册 2.基于责任链的设计模式 3.基于动态代理的plugin 4.拦截方法的interc ...
- Mybatis源码学习第六天(核心流程分析)之Executor分析
今Executor这个类,Mybatis虽然表面是SqlSession做的增删改查,其实底层统一调用的是Executor这个接口 在这里贴一下Mybatis查询体系结构图 Executor组件分析 E ...
- Mybatis源码学习第八天(总结)
源码学习到这里就要结束了; 来总结一下吧 Mybatis的总体架构 这次源码学习我们,学习了重点的模块,在这里我想说一句,源码的学习不是要所有的都学,一行一行的去学,这是错误的,我们只需要学习核心,专 ...
- ibatis源码学习1_整体设计和核心流程
背景介绍ibatis实现之前,先来看一段jdbc代码: Class.forName("com.mysql.jdbc.Driver"); String url = "jdb ...
随机推荐
- NIPS2018最佳论文解读:Neural Ordinary Differential Equations
NIPS2018最佳论文解读:Neural Ordinary Differential Equations 雷锋网2019-01-10 23:32 雷锋网 AI 科技评论按,不久前,NeurI ...
- 几个主流浏览器 Window.open打开新窗口 、模拟a标签打开新窗口的 表现
Window.open打开新窗口 1.常用浏览器打开新窗口(正常打开window.open)的的不同表现形式(PC/移动端) 2.Window.open在异步处理中打开(_blank) a标签在异步处 ...
- Node.js Express项目搭建
讲干货,不啰嗦,Express 是一个简洁而灵活的 node.js Web应用框架,使用 Express 可以快速地搭建一个完整功能的网站.本教程介绍如何从零开始搭建Express项目. 开发环境:w ...
- ORACLE和SQL查询库数据量
ORACLE根据账号查询每张表数据量: select t.table_name,t.num_rows from user_tables t ORDER BY NUM_ROWS DESC; SQL SE ...
- 每天一个Linux命令之:chage
命令简介: 该命令用于密码时效管理.它可以修改账号和密码的有效期.对于chage命令的描述如下所示: The chage command changes the number of days betw ...
- go语言入门(9)文本文件处理
1,字符串处理 字符串在开发中经常用到,包括用户的输入,数据库读取的数据等,我们经常需要对字符串进行分割.连接.转换等操作,我们可以通过Go标准库中的strings和strconv两个包中的函数进行相 ...
- Appium|Locator Strategy ... is not supported for this session
appim server log InvalidSelectorError: Locator Strategy 'xpath,//android.widget.TextView[@resource-i ...
- sql 基础语法使用
SQL的一些基础查询语法 基础.限定.模糊查询 关键字都是大写. 使用 BETWEENN AND 的时候小的数字或者日期放到 AND(并且) 的面前,大的一个放到AND 后面. 示例 ...
- 【异常】ERROR main:com.cloudera.enterprise.dbutil.SqlFileRunner: Exception while executing ddl scripts. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'ROLES' already exists
1 详细异常 2019-10-11 10:33:55,865 INFO main:com.cloudera.server.cmf.Main: ============================= ...
- MySQL跨表更新SQL
1 sql范式 把s表中的city_name的值设置为city表中的name,关联条件是city_code 和 code update student s, city c set s.city_na ...