MyBatis 缓存|学习笔记

简介: 快速学习MyBatis 缓存

开发者学堂课程【高校精品课-厦门大学 -JavaEE 平台技术MyBatis 缓存学习笔记,与课程紧密联系,让用户快速学习知识

课程地址:https://developer.aliyun.com/learning/course/80/detail/15968


MyBatis 缓存


内容介绍

一、前言

二、MyBatis 的两种种类

三、MyBatis 判断查询相同的依据

四、MyBatis 对于实现一二级缓存的方法

五、一级缓存和二级缓存的缺点


一、前言

之前提到过在应用服务器上的 ORM 框架的 MyBatis 提供了数据库查询结果缓存的功能,它可以把前面数据库查询的结果放在缓存里面,再次使用的时候就不必查询数据库了,从而降低了数据库的负涨。


二、MyBatis 的两种种类

MyBatis 提供了一级缓存和二级缓存两种不同的缓存。

1、基本介绍

(1)一级缓存

一级缓存是在单个的事务中间把数据结果缓存下来。

(2)二级缓存

二级缓存是在整个应用服务器之上,只要之前的事务查询过这项数据,这个数据就会缓存到 MyBatis 数据库的缓存之中。


三、MyBatis 判断查询相同的依据

1、Statement 的ID 相同

第一是查询的 ID,就是在 xml 中间以及在 Mapper 的接口中间所定义的接口名接口的方法名,以及在 xml 中间所定义的 ID,首先 ID 要是相同的。

2、预编译的 SQL 语句相同

因为在里面可能要写动态的 SQL 语句,所以第二个条件是判断这次查询所产生的预编译的 SQL 语句是相同的。

3、查询的参数一样

第三个是判断要绑定到 SQL 语句的查询条件的参数值是相同的。

如果ID 相同,预编译的 SQL 语句相同以及绑定的参数值相同,MyBatis 框架就认为这是同一个查询。它会用一个算法把这三个条件生成一个键值,然后以键值和结果存到 HashMap 中。如果后续的查询算到的键值是完全相同的,就会从

HashMap 中把数据取出并返回给应用服务器,这样就不必查询数据库了。

如果有执行的 update、insert 和 delete 语句的时候,它就会清空键值和缓存,从而使得重新执行数据库的查询。一级缓存是在一个事务里面的,所以在开启事务以后,在这个事务中只要有查询过的结果和语句,就不会再次进入数据库进行查询

了。


四、Batis 对于实现一二级缓存的方法

1、MyBatis 实现一级缓存的方法

上一次讲到了 MyBatis 和 SqlSession,就是一个 Sql 的绘画,把对于 MyBatis 框架的接口的调用转成 Sql 语句。在 Sql 的绘画中间有一个 Executor,它就是负责具体地把接口的调用变成 xml 中间的 Sql 语句的映射的机制。Executor 中有一个 local cache 本地缓存,所以当用户发起查询的时候,MyBatis 的 SqlSession 生成

Map的Statement,

图片14.png

就是按照前面的三个条件依据 xml 的定义生成 Sql 语句,然后按照三个条件在本地缓存中找寻这样的查询是否执行过。如果有执行过的就可以直接在本地缓存中取出返回给客户。

如果没有的话就会在数据库进行查询,把查询的结果返回给客户并同时保存到本地缓存中。这样的 SqlSession 是在一个事务中建立的。

每一个事务会开启一个 SqlSession,在事务结束后就会把 SqlSession 关闭,所以这样的缓存就只存在一个事务里面,所以将其称作一级缓存。不开启事务

一级缓存就是不存在的。

2、MyBatis 中间二级缓存的实现机制

二级缓存是在一级缓存的基础上来实现的。二级缓存也称其为 Map 级的缓存,也就是Map 中间的一个 namespace。在每一个 Map 的 xml 中间都定义了一个 namespace,所以在每一个 namespace 的上面如果不同的SqlSession 执行的查询是相同的,就会把上次的查询结果提取出来,从而最大程度的减少

数据库的查询。

图片15.png

在 MyBatis 中间其实做了一个装饰器模式,也就是与SqlSession 的前面一级缓存的方法是相同的,是通过 SqlSession 去完成对于接口的调用到 SQL 语句的映射的。在 SqlSession Executor 的前面放置了一个 Caching Executor 的装饰器的对象。所以一个查询有用户申请来执行的时候,首先需要经过 Caching Executor,它首先是在 namespace 级的一个缓存中进行查找,查找在 namespace 中是否有相同的查询。如果没有的话就会交给在一级缓存中提到的 Executor 进行查询。

在 Executor 中进行的操作和在一级缓存中是完全相同的。对于返回的结果 Caching Executor 就会放在 namespace 的二级缓存中,从而在另一个事务中间执行查询的时候 Caching Executor 就会从 namespace 中间把前一次查询所缓存下来的数据都进行返回。这就是二级缓存的实现机制。

 

五、一级缓存和二级缓存的缺点

1、一级缓存

在一个事务中间其实会很少把同一个查询执行两次,所以一级缓存对于一般的应用

程序而言意义不大。

2、二级缓存

(1)难以支持应用服务器集群

二级缓存的意义是不大的,但由于 MyBatis 的二级缓存是在应用服务器这个级别来做的缓存。也就是不同的应用服务器其实会做不同的二级缓存。而通常所做的大型的系统来说是不止一台服务器的,所以 MyBatis 的二级缓存是无法在应用服务器集

群的层面上进行缓存的,这是它的第一个缺点。

(2)不能高效利用内存

第二个缺点是二级缓存其实是未区分的进行缓存,只要是对数据库的查询都会把它缓存下来,不管以后是否有会重复用到的可能性。这样不加选择的缓存其实会占用大量的内存空间,而且内存是有限的,就一定会有某种算法把不需要的数据清除出

去,所以这样也会降低缓存的效果。

因为缓存所需要用到的内存是一个非常有限的资源,所以在做应用服务器级的缓存时往往希望会有一种更为节约或者是更加有效的方式来使用这些有限的内存。这个更多的会采用基于 redis 的一种分布式缓存的方式来实现缓存。

相关文章
|
1月前
|
缓存 Java 数据库连接
Mybatis缓存相关面试题有多卷
使用 MyBatis 缓存机制需要注意以下几点: 对于频繁更新和变动的数据,不适合使用缓存。 对于数据的一致性要求比较高的场景,不适合使用缓存。 如果配置了二级缓存,需要确保缓存的数据不会影响到其他业务模块的数据。 在使用缓存时,需要注意缓存的命中率和缓存的过期策略,避免缓存过期导致查询性能下降。
53 0
|
17天前
|
SQL 缓存 Java
MYBATIS缓存
MYBATIS缓存
|
4天前
|
SQL Java 数据库连接
MyBatis-Plus学习笔记(1):环境搭建以及基本的CRUD操作
MyBatis-Plus学习笔记(1):环境搭建以及基本的CRUD操作
|
12天前
|
缓存 NoSQL Java
在 SSM 架构(Spring + SpringMVC + MyBatis)中,可以通过 Spring 的注解式缓存来实现 Redis 缓存功能
【6月更文挑战第18天】在SSM(Spring+SpringMVC+MyBatis)中集成Redis缓存,涉及以下步骤:添加Spring Boot的`spring-boot-starter-data-redis`依赖;配置Redis连接池(如JedisPoolConfig)和连接工厂;在Service层使用`@Cacheable`注解标记缓存方法,指定缓存名和键生成策略;最后,在主配置类启用缓存注解。通过这些步骤,可以利用Spring的注解实现Redis缓存。
37 2
|
2天前
|
SQL 缓存 Java
Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件
Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件
|
6天前
|
缓存 Java 数据库连接
MyBatis的缓存功能总结
MyBatis的缓存功能总结
|
1月前
|
XML 缓存 Java
MyBatis二级缓存解密:深入探究缓存机制与应用场景
MyBatis二级缓存解密:深入探究缓存机制与应用场景
192 2
MyBatis二级缓存解密:深入探究缓存机制与应用场景
|
1月前
|
存储 缓存 Java
探秘MyBatis缓存原理:Cache接口与实现类源码分析
探秘MyBatis缓存原理:Cache接口与实现类源码分析
45 2
探秘MyBatis缓存原理:Cache接口与实现类源码分析
|
1月前
|
缓存 Java 数据库连接
MyBatis三级缓存实战:高级缓存策略的实现与应用
MyBatis三级缓存实战:高级缓存策略的实现与应用
55 0
MyBatis三级缓存实战:高级缓存策略的实现与应用
|
1月前
|
缓存 Java 数据库连接
【Mybatis】说一下 mybatis 的一级缓存和二级缓存
【Mybatis】说一下 mybatis 的一级缓存和二级缓存