目录
一、mybatis的二级缓存
1、实例演示代码
Emp.java代码
//实体类_有参构造、无参构造、getter和Setter方法、tostring方法
package com.atguigu.mybatis.pojo;
import java.io.Serializable;
public class Emp implements Serializable {
private Integer empId;
private String empName;
private Integer age;
private String gender;
public Emp(Integer empId, String empName, Integer age, String gender) {
this.empId = empId;
this.empName = empName;
this.age = age;
this.gender = gender;
}
public Emp() {
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
@Override
public String toString() {
return "Emp{" +
"empId=" + empId +
", empName='" + empName + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
CacheMapper.java代码
package com.atguigu.mybatis.mapper;
import com.atguigu.mybatis.pojo.Emp;
import org.apache.ibatis.annotations.Param;
public interface CacheMapper {
/* *
*
*根据员工id查询员工信息
* @param empId
* @return com.atguigu.mybatis.pojo.Emp
* @author yzh
* @create 2025/2/24
**/
Emp getEmpById(@Param("empId") Integer empId);
/* *
*
* 添加员工信息
* @param emp
* @return void
* @author yzh
* @create 2025/2/24
**/
void insertEmp(Emp emp);
}
CacheMapper.xml代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mybatis.mapper.CacheMapper">
<cache />
<!--Emp getEmpById(@Param("empId") Integer empId);-->
<select id="getEmpById" resultType="Emp">
select *
from t_emp where emp_id = #{empId};
</select>
<!--void insertEmp(Emp emp);-->
<insert id="insertEmp">
insert into t_emp values (null,#{empName},#{age},#{gender},null)
</insert>
</mapper>
CacheMapperTest.java代码
import com.atguigu.mybatis.mapper.CacheMapper;
import com.atguigu.mybatis.pojo.Emp;
import com.atguigu.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class CacheMapperTest {
@Test
public void testCache1() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession1 = sqlSessionFactory.openSession( true);
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
Emp emp1 = mapper1.getEmpById(1);
System.out.println(emp1);
sqlSession1.close();
SqlSession sqlSession2 = sqlSessionFactory.openSession( true);
CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
Emp emp2 = mapper2.getEmpById(1);
System.out.println(emp2);
sqlSession2.close();
}
}
2、输出结果
DEBUG 02-24 11:24:39,696 Cache Hit Ratio [com.atguigu.mybatis.mapper.CacheMapper]: 0.0 (LoggingCache.java:60)
DEBUG 02-24 11:24:39,859 ==> Preparing: select * from t_emp where emp_id = ?; (BaseJdbcLogger.java:137)
DEBUG 02-24 11:24:39,888 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137)
DEBUG 02-24 11:24:39,912 <== Total: 1 (BaseJdbcLogger.java:137)
Emp{empId=1, empName='张三', age=20, gender='男'}
WARN 02-24 11:24:39,919 As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66 (SerialFilterChecker.java:46)
DEBUG 02-24 11:24:39,925 Cache Hit Ratio [com.atguigu.mybatis.mapper.CacheMapper]: 0.5 (LoggingCache.java:60)
Emp{empId=1, empName='张三', age=20, gender='男'}
进程已结束,退出代码为 0
3、实例分析以及知识总结
1. 实例演示代码分析
在提供的代码中,CacheMapperTest
类中的 testCache1
方法展示了 MyBatis 二级缓存的使用。以下是代码的执行流程:
-
第一次查询:
-
通过
SqlSessionFactory
创建SqlSession1
。 -
使用
SqlSession1
获取CacheMapper
的实例mapper1
。 -
调用
mapper1.getEmpById(1)
查询员工信息。 -
由于是第一次查询,缓存中没有数据,因此会从数据库中查询数据,并将查询结果存入二级缓存。
-
查询结果打印为:
Emp{empId=1, empName='张三', age=20, gender='男'}
。
-
-
第二次查询:
-
关闭
SqlSession1
,此时一级缓存中的数据会被清空,但二级缓存中的数据仍然保留。 -
通过
SqlSessionFactory
创建SqlSession2
。 -
使用
SqlSession2
获取CacheMapper
的实例mapper2
。 -
调用
mapper2.getEmpById(1)
查询员工信息。 -
由于二级缓存中已经存在该数据,因此直接从缓存中获取数据,而不需要再次访问数据库。
-
查询结果打印为:
Emp{empId=1, empName='张三', age=20, gender='男'}
。
-
2. 输出结果分析
-
第一次查询:
-
Cache Hit Ratio [com.atguigu.mybatis.mapper.CacheMapper]: 0.0
:表示缓存命中率为 0,即第一次查询时缓存中没有数据。 -
==> Preparing: select * from t_emp where emp_id = ?;
:表示 MyBatis 正在准备 SQL 查询。 -
==> Parameters: 1(Integer)
:表示 SQL 查询的参数为1
。 -
<== Total: 1
:表示查询结果返回了 1 条记录。 -
Emp{empId=1, empName='张三', age=20, gender='男'}
:查询结果。
-
-
第二次查询:
-
Cache Hit Ratio [com.atguigu.mybatis.mapper.CacheMapper]: 0.5
:表示缓存命中率为 50%,即第二次查询时从缓存中获取了数据。 -
Emp{empId=1, empName='张三', age=20, gender='男'}
:查询结果。
-
3. MyBatis 二级缓存知识总结
-
二级缓存的作用范围:
-
MyBatis 的二级缓存是
SqlSessionFactory
级别的,即通过同一个SqlSessionFactory
创建的多个SqlSession
可以共享二级缓存。
-
-
开启二级缓存的条件:
-
在 MyBatis 核心配置文件中,设置全局配置属性
cacheEnabled="true"
(默认值为true
,通常不需要显式设置)。 -
在映射文件中使用
<cache />
标签开启二级缓存。 -
二级缓存必须在
SqlSession
关闭或提交之后才会生效。 -
查询的数据所转换的实体类必须实现
Serializable
接口。
-
-
二级缓存失效的情况:
-
如果在两次查询之间执行了任意的增删改操作,MyBatis 会自动清空一级缓存和二级缓存,以确保数据的一致性。
-
-
缓存命中率:
-
缓存命中率表示从缓存中获取数据的比例。在第一次查询时,缓存命中率为 0,因为数据是从数据库中查询的。在第二次查询时,缓存命中率为 50%,因为数据是从缓存中获取的。
-
二、mybatis的二级缓存相关配置和缓存查询顺序
1. cache
标签的属性配置
在 MyBatis 的 Mapper 配置文件中,可以通过 <cache />
标签配置二级缓存的行为。以下是 <cache />
标签的常用属性:
① eviction
属性:缓存回收策略
-
默认值:
LRU
-
可选值:
-
LRU
(Least Recently Used)- 最近最少使用:移除最长时间不被使用的对象。 -
FIFO
(First In First Out)- 先进先出:按对象进入缓存的顺序来移除它们。 -
SOFT
- 软引用:移除基于垃圾回收器状态和软引用规则的对象。 -
WEAK
- 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
-
② flushInterval
属性:刷新间隔
-
单位:毫秒
-
默认值:不设置(无刷新间隔)
-
作用:设置缓存的自动刷新时间间隔。例如,设置为
60000
表示缓存每 60 秒刷新一次。
③ size
属性:缓存对象的最大数量
-
类型:正整数
-
默认值:无
-
作用:设置缓存中最多可以存储的对象数量。如果缓存对象数量超过设置的值,会根据
eviction
策略移除对象。
④ readOnly
属性:缓存是否只读
-
默认值:
false
-
可选值:
-
true
:只读缓存。所有调用者会共享缓存对象的相同实例,性能较高,但缓存对象不能被修改。 -
false
:读写缓存。每次返回缓存对象的拷贝(通过序列化),性能较低,但更安全。
-
2. 缓存查询顺序
MyBatis 的缓存查询顺序如下:
-
先查询二级缓存:
-
二级缓存是
SqlSessionFactory
级别的缓存,多个SqlSession
可以共享。 -
如果二级缓存中存在查询结果,则直接返回缓存数据,不再访问数据库。
-
-
如果二级缓存未命中,再查询一级缓存:
-
一级缓存是
SqlSession
级别的缓存,只在同一个SqlSession
内有效。 -
如果一级缓存中存在查询结果,则直接返回缓存数据。
-
-
如果一级缓存也未命中,则查询数据库:
-
如果一级缓存和二级缓存中都没有查询结果,则访问数据库获取数据。
-
查询结果会先存入一级缓存,然后在
SqlSession
关闭或提交时,一级缓存中的数据会写入二级缓存。
-
3. 示例配置
以下是一个完整的 <cache />
标签配置示例:
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
-
eviction="FIFO"
:使用先进先出的缓存回收策略。 -
flushInterval="60000"
:设置缓存每 60 秒刷新一次。 -
size="512"
:缓存中最多存储 512 个对象。 -
readOnly="true"
:缓存为只读模式,性能较高但不允许修改缓存对象。
4. 缓存查询顺序的代码示例
以下是一个缓存查询顺序的代码示例:
@Test
public void testCacheOrder() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// 第一次查询
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
Emp emp1 = mapper1.getEmpById(1); // 查询数据库,存入一级缓存
System.out.println(emp1);
sqlSession1.close(); // 一级缓存数据写入二级缓存
// 第二次查询
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
Emp emp2 = mapper2.getEmpById(1); // 从二级缓存中获取数据
System.out.println(emp2);
sqlSession2.close();
// 第三次查询
SqlSession sqlSession3 = sqlSessionFactory.openSession(true);
CacheMapper mapper3 = sqlSession3.getMapper(CacheMapper.class);
Emp emp3 = mapper3.getEmpById(1); // 从二级缓存中获取数据
System.out.println(emp3);
sqlSession3.close();
}
三、整合第三方缓存EHcache ——操作步骤
1、添加依赖
在 pom.xml
中添加以下依赖:
<!-- Mybatis EHCache整合包 -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.1</version>
</dependency>
<!-- slf4j日志门面的一个具体实现 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
2、各 jar 包功能
Jar 包名称 | 作用 |
---|---|
mybatis-ehcache | MyBatis 和 EHCache 的整合包,用于将 EHCache 作为 MyBatis 的二级缓存实现。 |
ehcache | EHCache 的核心包,提供缓存存储、缓存策略、缓存管理等功能。 |
slf4j-api | SLF4J 日志门面包,提供统一的日志接口,支持多种日志实现。 |
logback-classic | 支持 SLF4J 门面接口的一个具体实现,提供高性能的日志功能。 |
3、创建 EHCache 配置文件 ehcache.xml
创建 ehcache.xml
文件,配置示例如下:
<?xml version="1.0" encoding="utf-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="..//config/ehcache.xsd">
<!-- 磁盘保存路径 -->
<diskStore path="D:\atiguigu\ehcache"/>
<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
4、设置二级缓存的类型
在 MyBatis 的 映射文件中,通过 <cache />
标签指定使用 EHCache 作为二级缓存实现:
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
5、加入 logback 日志
在 logback.xml
中配置日志级别,以便查看 EHCache 的运行日志:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<!-- 指定日志输出的位置 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出的格式 -->
<!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%-5level] [%thread] %logger [%msg]%n</pattern>
</encoder>
</appender>
<!-- 设置全局日志级别。日志级别按顺序分别是:DEBUG、INFO、WARN、ERROR -->
<!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 -->
<root level="DEBUG">
<!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender -->
<appender-ref ref="STDOUT"/>
</root>
<!-- 根据特殊需求指定局部日志级别 -->
<logger name="com.atguigu.mybatis.mapper" level="DEBUG"/>
</configuration>
6、EHCache 配置文件说明
属性名 |
是否必须 | 作用 |
---|---|---|
maxElementsInMemory | 是 | 在内存中缓存的 element 的最大数目。 |
maxElementsOnDisk | 是 | 在磁盘上缓存的 element 的最大数目。如果为 0,表示无穷大。 |
eternal | 是 | 设定缓存中的 elements 是否永远不过期。如果为 true ,缓存数据始终有效;如果为 false ,则根据 timeToIdleSeconds 和 timeToLiveSeconds 判断过期。 |
overflowToDisk | 是 | 设定当内存缓存溢出时,是否将过期的 element 缓存到磁盘上。 |
timeToIdleSeconds | 否 | 当缓存在 EhCache 中的数据前后两次访问的时间超过 timeToIdleSeconds 时,这些数据会被删除。默认值为 0,表示可闲置时间无穷大。 |
timeToLiveSeconds | 否 | 缓存 element 的有效生命期。默认值为 0,表示 element 存活时间无穷大。 |
diskSpoolBufferSizeMB | 否 | DiskStore(磁盘缓存)的缓存区大小。默认是 30MB。每个 Cache 都应该有自己的一个缓冲区。 |
diskPersistent | 否 | 在 VM 重启时是否启用磁盘保存 EhCache 中的数据。默认是 false 。 |
diskExpiryThreadIntervalSeconds | 否 | 磁盘缓存清理线程的运行间隔。默认是 120 秒。每 120 秒,相应的线程会进行一次 EhCache 中数据的清理工作。 |
7、实例测试
7.1测试代码逻辑
@Test
public void testCacheOrder() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// 第一次查询
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
Emp emp1 = mapper1.getEmpById(1); // 查询数据库,存入一级缓存
System.out.println(emp1);
sqlSession1.close(); // 一级缓存数据写入二级缓存
// 第二次查询
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
Emp emp2 = mapper2.getEmpById(1); // 从二级缓存中获取数据
System.out.println(emp2);
sqlSession2.close();
// 第三次查询
SqlSession sqlSession3 = sqlSessionFactory.openSession(true);
CacheMapper mapper3 = sqlSession3.getMapper(CacheMapper.class);
Emp emp3 = mapper3.getEmpById(1); // 从二级缓存中获取数据
System.out.println(emp3);
sqlSession3.close();
}
7.2测试输出日志
以下是测试执行时的日志输出,结合代码逻辑进行分析:
7.2.1. 日志初始化
12:47:31,695 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
12:47:31,696 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
12:47:31,696 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/C:/Users/%e6%9d%a8%e6%99%ba%e6%85%a7/Desktop/SSM/mybatis_cache/target/classes/logback.xml]
12:47:31,763 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
12:47:31,767 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
12:47:31,773 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
12:47:31,804 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
12:47:31,804 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
12:47:31,806 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.atguigu.mybatis.mapper] to DEBUG
12:47:31,806 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
12:47:31,807 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@43738a82 - Registering current configuration as safe fallback point
-
说明:
-
日志系统初始化,加载
logback.xml
配置文件。 -
配置了控制台日志输出,日志级别设置为
DEBUG
。
-
7.2.2. MyBatis 初始化
12:47:31.812 [DEBUG] [main] org.apache.ibatis.logging.LogFactory [Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.]
12:47:31.818 [DEBUG] [main] org.apache.ibatis.io.VFS [Class not found: org.jboss.vfs.VFS]
12:47:31.818 [DEBUG] [main] org.apache.ibatis.io.JBoss6VFS [JBoss 6 VFS API is not available in this environment.]
12:47:31.819 [DEBUG] [main] org.apache.ibatis.io.VFS [Class not found: org.jboss.vfs.VirtualFile]
12:47:31.819 [DEBUG] [main] org.apache.ibatis.io.VFS [VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.]
12:47:31.820 [DEBUG] [main] org.apache.ibatis.io.VFS [Using VFS adapter org.apache.ibatis.io.DefaultVFS]
-
说明:
-
MyBatis 初始化日志系统,使用
Slf4jImpl
作为日志适配器。 -
检查并加载 VFS(虚拟文件系统)实现,最终使用默认的
DefaultVFS
。
-
7.2.3. EHCache 初始化
12:47:31.931 [DEBUG] [main] net.sf.ehcache.config.ConfigurationFactory [Configuring ehcache from ehcache.xml found in the classpath: file:/C:/Users/%e6%9d%a8%e6%99%ba%e6%85%a7/Desktop/SSM/mybatis_cache/target/classes/ehcache.xml]
12:47:31.931 [DEBUG] [main] net.sf.ehcache.config.ConfigurationFactory [Configuring ehcache from URL: file:/C:/Users/%e6%9d%a8%e6%99%ba%e6%85%a7/Desktop/SSM/mybatis_cache/target/classes/ehcache.xml]
12:47:31.934 [DEBUG] [main] net.sf.ehcache.config.ConfigurationFactory [Configuring ehcache from InputStream]
12:47:31.945 [DEBUG] [main] net.sf.ehcache.config.BeanHandler [Ignoring ehcache attribute xmlns:xsi]
12:47:31.945 [DEBUG] [main] net.sf.ehcache.config.BeanHandler [Ignoring ehcache attribute xsi:noNamespaceSchemaLocation]
12:47:31.946 [DEBUG] [main] net.sf.ehcache.config.DiskStoreConfiguration [Disk Store Path: D:\atiguigu\ehcache]
12:47:31.959 [DEBUG] [main] net.sf.ehcache.CacheManager [Creating new CacheManager with default config]
-
说明:
-
EHCache 从
ehcache.xml
文件中加载配置。 -
配置磁盘缓存路径为
D:\atiguigu\ehcache
。 -
创建
CacheManager
实例。
-
7.2.4. 第一次查询
12:47:32.393 [DEBUG] [main] com.atguigu.mybatis.mapper.CacheMapper [Cache Hit Ratio [com.atguigu.mybatis.mapper.CacheMapper]: 0.0]
12:47:32.400 [DEBUG] [main] org.apache.ibatis.transaction.jdbc.JdbcTransaction [Opening JDBC Connection]
12:47:32.591 [DEBUG] [main] org.apache.ibatis.datasource.pooled.PooledDataSource [Created connection 1396431506.]
12:47:32.594 [DEBUG] [main] com.atguigu.mybatis.mapper.CacheMapper.getEmpById [==> Preparing: select * from t_emp where emp_id = ?;]
12:47:32.617 [DEBUG] [main] com.atguigu.mybatis.mapper.CacheMapper.getEmpById [==> Parameters: 1(Integer)]
12:47:32.638 [DEBUG] [main] com.atguigu.mybatis.mapper.CacheMapper.getEmpById [<== Total: 1]
Emp{empId=1, empName='张三', age=20, gender='男'}
12:47:32.640 [DEBUG] [main] net.sf.ehcache.store.disk.Segment [put added 0 on heap]
12:47:32.642 [DEBUG] [main] org.apache.ibatis.transaction.jdbc.JdbcTransaction [Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@533bda92]]
12:47:32.642 [DEBUG] [main] org.apache.ibatis.datasource.pooled.PooledDataSource [Returned connection 1396431506 to pool.]
-
说明:
-
第一次查询时,缓存命中率为
0.0
,表示缓存中没有数据。 -
从数据库中查询数据,并将结果存入一级缓存。
-
查询结果:
Emp{empId=1, empName='张三', age=20, gender='男'}
。 -
关闭
SqlSession1
时,一级缓存数据写入二级缓存。
-
7.2.5. 第二次查询
12:47:32.642 [DEBUG] [main] com.atguigu.mybatis.mapper.CacheMapper [Cache Hit Ratio [com.atguigu.mybatis.mapper.CacheMapper]: 0.5]
Emp{empId=1, empName='张三', age=20, gender='男'}
-
说明:
-
第二次查询时,缓存命中率为
0.5
,表示从二级缓存中获取数据。 -
查询结果与第一次相同,直接从缓存中返回。
-
7.2.6. 第三次查询
12:47:32.642 [DEBUG] [main] com.atguigu.mybatis.mapper.CacheMapper [Cache Hit Ratio [com.atguigu.mybatis.mapper.CacheMapper]: 0.6666666666666666]
Emp{empId=1, empName='张三', age=20, gender='男'}
-
说明:
-
第三次查询时,缓存命中率为
0.6666666666666666
,表示再次从二级缓存中获取数据。 -
查询结果与之前相同,直接从缓存中返回。
-
7.2.7、测试结果总结
-
缓存命中率:
-
第一次查询:
0.0
(未命中,从数据库查询)。 -
第二次查询:
0.5
(命中,从二级缓存获取)。 -
第三次查询:
0.6666666666666666
(命中,从二级缓存获取)。
-
-
查询结果:
-
三次查询结果均为:
Emp{empId=1, empName='张三', age=20, gender='男'}
。
-