深入理解Mybatis(一)架构设计

前言

ORM是Object和Relation之间的映射,包括Object->Relation和Relation->Object两方面。Hibernate是个完整的ORM框架,而MyBatis完成的是Relation->Object,也就是其所说的Data Mapper Framework。JPA是ORM框架标准,主流的ORM框架都实现了这个标准。MyBatis没有实现JPA,它和ORM框架的设计思路不完全一样。MyBatis是拥抱SQL,而ORM则更靠近面向对象,不建议写SQL,实在要写,则推荐你用框架自带的类SQL代替。

最典型的ORM 框架是Hibernate,它是全自动ORM框架,而MyBatis是半自动的。Hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成SQL。而MyBatis仅有基本的字段映射,对象数据以及对象实际关系仍然需要通过手写SQL来实现和管理。

MyBatis是一个优秀的持久层框架,它对JDBC的操作数据库的过程进行封装。

MyBatis的基本工作原理就是:先封装SQL,接着调用JDBC操作数据库,最后把数据库返回的表结果封装成Java类。

一、Mybatis的框架设计

img

1 接口层

MyBatis和数据库的交互有两种方式:

  • 使用传统的MyBatis提供的API;
  • 使用Mapper接口
1.1使用传统的MyBatis提供的API

这是传统的传递***Statement Id*** 和查询参数给 SqlSession 对象,使用 SqlSession对象完成和数据库的交互,这种方式固然很简单和实用,但是它不符合面向对象语言的概念和面向接口编程的编程习惯。由于面向接口的编程是面向对象的大趋势,MyBatis 为了适应这一趋势,增加了第二种使用***MyBatis*** 支持接口(Interface)调用方式。

1.2使用Mapper接口

MyBatis 将配置文件中的每一个 节点抽象为一个 Mapper 接口,而这个接口中声明的方法和跟 节点中的<select|update|delete|insert> 节点项对应,即<select|update|delete|insert> 节点的id值为Mapper 接口中的方法名称,parameterType 值表示Mapper 对应方法的入参类型,而resultMap 值则对应了Mapper 接口表示的返回值类型或者返回结果集的元素类型。

2 数据处理层

数据处理层可以说是***MyBatis*** 的核心,从大的方面上讲,它要完成两个功能:

a. 通过传入参数构建动态SQL语句;

b. SQL语句的执行以及封装查询结果集成List

2.1. 参数映射和动态SQL语句生成

动态语句生成可以说是**MyBatis框架非常优雅的一个设计,MyBatis 通过传入的参数值,使用 Ognl 来动态地构造SQL语句,使得MyBatis 有很强的灵活性和扩展性。

参数映射指的是对于java 数据类型和jdbc数据类型之间的转换:这里有包括两个过程:查询阶段,我们要将java类型的数据,转换成jdbc类型的数据,通过 preparedStatement.setXXX() 来设值;另一个就是对resultset查询结果集的jdbcType 数据转换成java 数据类型。

2.2. SQL语句的执行以及封装查询结果集成List

动态SQL语句生成之后,MyBatis 将执行SQL语句,并将可能返回的结果集转换成***List*** 列表。MyBatis 在对结果集的处理中,支持结果集关系一对多和多对一的转换,并且有两种支持方式,一种为嵌套查询语句的查询,还有一种是嵌套结果集的查询。

3 框架支撑层

3.1. 事务管理机制

事务管理机制对于***ORM***框架而言是不可缺少的一部分,事务管理机制的质量也是考量一个***ORM***框架是否优秀的一个标准。对数据库的事务而言,应该具有以下几点:创建(create)、提交(commit)、回滚(rollback)、关闭(close)。对应地,MyBatis将事务抽象成了Transaction接口。

MyBatis的事务管理分为两种形式:

一、使用***JDBC***的事务管理机制:即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())、关闭(close())等

二、使用***MANAGED***的事务管理机制:这种机制***MyBatis***自身不会去实现事务管理,而是让程序的容器如(JBOSS,Weblogic)来实现对事务的管理

3.2. 连接池管理机制

由于创建一个数据库连接所占用的资源比较大, 对于数据吞吐量大和访问量非常大的应用而言,连接池的设计就显得非常重要。对于需要频繁地跟数据库交互的应用程序,可以在创建了***Connection***对象,并操作完数据库后,可以不释放掉资源,而是将它放到内存中,当下次需要操作数据库时,可以直接从内存中取出***Connection***对象,不需要再创建了,这样就极大地节省了创建***Connection***对象的资源消耗。由于内存也是有限和宝贵的,这又对我们对内存中的***Connection***对象怎么有效地维护提出了很高的要求。我们将在内存中存放***Connection***对象的容器称之为 连接池(Connection Pool)。下面让我们来看一下***MyBatis***的线程池是怎样实现的。

3.3. 缓存机制

为了提高数据利用率和减小服务器和数据库的压力,MyBatis 会对于一些查询提供会话级别的数据缓存,会将对某一次查询,放置到***SqlSession*** 中,在允许的时间间隔内,对于完全相同的查询,MyBatis 会直接将缓存结果返回给用户,而不用再到数据库中查找。

3.4.SQL语句的配置方式

传统的***MyBatis*** 配置***SQL*** 语句方式就是使用XML文件进行配置的,但是这种方式不能很好地支持面向接口编程的理念,为了支持面向接口的编程,MyBatis 引入了***Mapper***接口的概念,面向接口的引入,对使用注解来配置SQL 语句成为可能,用户只需要在接口上添加必要的注解即可,不用再去配置***XML***文件了,但是,目前的MyBatis 只是对注解配置***SQL*** 语句提供了有限的支持,某些高级功能还是要依赖***XML***配置文件配置***SQL*** 语句。

4 引导层

引导层是配置和启动***MyBatis*** 配置信息的方式。MyBatis 提供两种方式来引导***MyBatis*** :基于XML配置文件的方式和基于***Java API*** 的方式。

二、MyBatis的主要构件及其相互关系

从MyBatis代码实现的角度来看,MyBatis的主要的核心部件有以下几个:

名称介绍
SqlSession作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能。
ExecutorMyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护。
StatementHandler封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。
ParameterHandler负责对用户传递的参数转换成JDBC Statement 所需要的参数。
ResultSetHandler负责将JDBC返回的ResultSet结果集对象转换成List类型的集合。
TypeHandler负责java数据类型和jdbc数据类型之间的映射和转换。
MappedStatementMappedStatement维护了一条<select|update|delete|insert>节点的封装。
SqlSource负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回。
BoundSql表示动态生成的SQL语句以及相应的参数信息。
ConfigurationMyBatis所有的配置信息都维持在Configuration对象之中。

(注:这里只是列出了我个人认为属于核心的部件,请读者不要先入为主,认为MyBatis就只有这些部件哦!每个人对MyBatis的理解不同,分析出的结果自然会有所不同)

它们的关系如下图所示:

img

三、MyBatis的核心流程

关于MyBatis的初始化过程:

image-20200708150700827

由上图所示,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使用。

MyBatis的工作原理如下图所示:

mybatis.png

上面中流程就是***MyBatis***内部核心流程,每一步流程的详细说明如下文所述:

(1)读取***MyBatis***的配置文件。mybatis-config.xml为MyBatis的全局配置文件,用于配置数据库连接信息。

(2)加载映射文件。映射文件即***SQL***映射文件,该文件中配置了操作数据库的SQL语句,需要在MyBatis配置文件mybatis-config.xml中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

(3)构造会话工厂。通过MyBatis的环境配置信息构建会话工厂***SqlSessionFactory***。

(4)创建会话对象。由会话工厂创建***SqlSession***对象,该对象中包含了执行SQL语句的所有方法。

(5)***Executor***执行器。MyBatis底层定义了一个***Executor***接口来操作数据库,它将根据***SqlSession***传递的参数动态地生成需要执行的***SQL***语句,同时负责查询缓存的维护。

(6)***MappedStatement***对象。在Executor接口的执行方法中有一个***MappedStatement***类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息。

(7)输入参数映射。输入参数类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输入参数映射过程类似于JDBC对***preparedStatement***对象设置参数的过程。

(8)输出结果映射。输出结果类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输出结果映射过程类似于JDBC对结果集的解析过程。

本文引用:

《深入理解mybatis原理》 MyBatis的架构设计以及实例分析

原理分析之二:框架整体设计

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值