MyBatis工作流程和缓存机制

MyBatis 的工作流程

  • 首先在mybaits启动的时候去解析配置文件,包括全局配置文件和映射器 配置文件把它们解析成一个 Configuration 对象
  • 接下来,是操作数据库的接口SqlSession,要获得一个会话 ,必 须 有 一 个 会 话 工 厂 SqlSessionFactory 。SqlSessionFactory 里面又必须包含我们的所有的配置信息,所以我们会通过一个 Builder 来创建工厂类
  • SqlSession 持有了一个 Executor 对象,用来封装对数据库的 操作,在执行器 Executor 执行 query 或者 update 操作的时候我们创建一系列的对象, 来处理参数、执行 SQL、处理结果集,这里我们把它简化成一个对象:StatementHandler

MyBatis 的架构分层与模块划分

 

MyBatis 缓存机制

.MyBatis 也有一级缓存和二级缓存,并且预留了集成第三方缓存的接口。MyBatis 跟缓存相关的类都在 cache 包里面,其中有一个 Cache 接口,只有一个默 认的实现类 PerpetualCache,它是用 HashMap 实现的。除此之外,还有很多的装饰器,通过这些装饰器可以额外实现很多的功能:回收策 略、日志记录、定时刷新等等

  • 一级缓存(本地缓存)

MyBatis 的一级缓存是在会话(SqlSession)层面进行缓 存的。MyBatis 的一级缓存是默认开启的

缓存只可能放在 Executor 里面维护——SimpleExecutor/ReuseExecutor/BatchExecutor 的父类BaseExecutor 的构造函数中持有了 PerpetualCache。

  • 二级缓存

MyBatis 用了一个装饰器的类来维护,就是 CachingExecutor。如果启用了 二级缓存,MyBatis 在创建 Executor 对象的时候会对 Executor 进行装饰

CachingExecutor 对于查询请求,会判断二级缓存是否有缓存结果,如果有就直接 返回,如果没有委派交给真正的查询器 Executor 实现类,比如 SimpleExecutor 来执行 查询,再走到一级缓存的流程。最后会把结果缓存起来,并且返回给用户

开启二级缓存的方法 

  1. 在 mybatis-config.xml 中配置<setting name="cacheEnabled" value="true"/> 默认true
  2. 在 Mapper.xml 中配置标签
<!-- 声明这个 namespace 使用二级缓存 -->
<cache type="org.apache.ibatis.cache.impl.PerpetualCache"
size="1024" <!—最多缓存对象个数,默认 1024-->
eviction="LRU" <!—回收策略-->
flushInterval="120000" <!—自动刷新时间 ms,未配置时只有调用时刷新-->
readOnly="false"/> <!—默认是 false(安全),改为 true 可读写时,对象必须支持序列
化 -->

Mapper.xml 配置了之后,select()会被缓存。update()、delete()、insert() 会刷新缓存。因为commit()方法被调用的时候才会调用 flushPendingEntries()真正写入缓存详情见

CachingExecutor和TransactionalCacheManager

有没有配置<cache>,决定了在 启动的时候会不会创建这个 mapper 的 Cache 对象

 

MyBatis 底层工作原理

#从这个demo开始流程
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlogById(1);

一、配置解析过程

build 方法这里面创建了一个 XMLConfigBuilder 对象,build(parser.parse());返回一个 //Configuration对象

二、会话创建过程

跟数据库的每一次连接,都需要创建一个会话,这个会话里面,需要包含一个 Executor 用来执行 SQL。Executor 又要指定事务类 型和执行器的类型。所以我们会先从 Configuration 里面拿到 Enviroment,Enviroment 里面就有事务工厂

三、获得 Mapper 对象

DefaultSqlSession 的 getMapper()方法,调用了 Configuration 的 getMapper() 方法又调用了 MapperRegistry 的 getMapper() 方法

四、执行 SQL

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值