美文网首页
Mybatis架构和源码剖析

Mybatis架构和源码剖析

作者: GavinZZW | 来源:发表于2021-03-14 22:35 被阅读0次

1 架构设计

image.png

我们把Mybatis的功能架构分为三层:

(1) API接⼝层:提供给外部使⽤的接⼝ API,开发⼈员通过这些本地API来操纵数据库。接⼝层⼀接收

到 调⽤请求就会调⽤数据处理层来完成具体的数据处理。

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

a. 使⽤传统的MyBati s提供的API ;

b. 使⽤Mapper代理的⽅式

(2) 数据处理层:负责具体的SQL查找、SQL解析、SQL执⾏和执⾏结果映射处理等。它主要的⽬的是根

据调⽤的请求完成⼀次数据库操作。

(3) 基础⽀撑层:负责最基础的功能⽀撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是

共 ⽤的东⻄,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的⽀撑


image.png

2 总体流程

(1) 加载配置并初始化

触发条件:加载配置⽂件

配置来源于两个地⽅,⼀个是配置⽂件(主配置⽂件conf.xml,mapper⽂件*.xml),—个是java代码中的

注解,将主配置⽂件内容解析封装到Configuration,将sql的配置信息加载成为⼀个mappedstatement

对象,存储在内存之中(2) 接收调⽤请求

触发条件:调⽤Mybatis提供的API

传⼊参数:为SQL的ID和传⼊参数对象

处理过程:将请求传递给下层的请求处理层进⾏处理。

(3) 处理操作请求

触发条件:API接⼝层传递请求过来

传⼊参数:为SQL的ID和传⼊参数对象

处理过程:

(A) 根据SQL的ID查找对应的MappedStatement对象。

(B) 根据传⼊参数对象解析MappedStatement对象,得到最终要执⾏的SQL和执⾏传⼊参数。

(C) 获取数据库连接,根据得到的最终SQL语句和执⾏传⼊参数到数据库执⾏,并得到执⾏结果。

(D) 根据MappedStatement对象中的结果映射配置对得到的执⾏结果进⾏转换处理,并得到最终的处

理 结果。

(E) 释放连接资源。

(4) 返回处理结果

将最终的处理结果返回。

3 延迟加载的实现

局部延迟加载

在association和collection标签中都有⼀个fetchType属性,通过修改它的值,可以修改局部的加载策略。

<!-- 开启⼀对多 延迟加载 -->
<resultMap id="userMap" type="user">
 <id column="id" property="id"></id>
 <result column="username" property="username"></result>
 <result column="password" property="password"></result>
全局延迟加载
在Mybatis的核⼼配置⽂件中可以使⽤setting标签修改全局的加载策略。
注意
7.。
 <result column="birthday" property="birthday"></result>
 <!--
 fetchType="lazy" 懒加载策略
 fetchType="eager" ⽴即加载策略
 -->
 <collection property="orderList" ofType="order" column="id" 
 select="com.lagou.dao.OrderMapper.findByUid" fetchType="lazy">
 </collection>
</resultMap> <select id="findAll" resultMap="userMap">
 SELECT * FROM `user`
</select>

全局延迟加载
在Mybatis的核⼼配置⽂件中可以使⽤setting标签修改全局的加载策略。

<settings>
 <!--开启全局延迟加载功能-->
 <setting name="lazyLoadingEnabled" value="true"/>
</settings>

注意的点

<!-- 关闭⼀对⼀ 延迟加载 -->
<resultMap id="orderMap" type="order">
 <id column="id" property="id"></id>
 <result column="ordertime" property="ordertime"></result>
 <result column="total" property="total"></result>
 <!--
 fetchType="lazy" 懒加载策略
 fetchType="eager" ⽴即加载策略
 -->
 <association property="user" column="uid" javaType="user"
 select="com.lagou.dao.UserMapper.findById" fetchType="eager"> 
</association>
</resultMap> <select id="findAll" resultMap="orderMap">
 SELECT * from orders
</select>

延迟加载原理实现

它的原理是,使⽤ CGLIB 或 Javassist( 默认 ) 创建⽬标对象的代理对象。当调⽤代理对象的延迟加载属
性的 getting ⽅法时,进⼊拦截器⽅法。⽐如调⽤ a.getB().getName() ⽅法,进⼊拦截器的
invoke(...) ⽅法,发现 a.getB() 需要延迟加载时,那么就会单独发送事先保存好的查询关联 B
对象的 SQL ,把 B 查询上来,然后调⽤ a.setB(b) ⽅法,于是 a 对象 b 属性就有值了,接着完
成 a.getB().getName() ⽅法的调⽤。这就是延迟加载的基本原理

总结:延迟加载主要是通过动态代理的形式实现,通过代理拦截到指定⽅法,执⾏数据加载。

4 Mybatis中的设计模式

image.png

相关文章

网友评论

      本文标题:Mybatis架构和源码剖析

      本文链接:https://www.haomeiwen.com/subject/eiaccltx.html