缓存即为存在内存中的临时数据.将用户经常查询的数据存放在缓存(内存)中,用户去查询数据就不用去每次去数据库中查询,而是去缓存中查询,从而提高了查询的效率,解决了高并发系统的性能问题.MyBatis提供了两种缓存机制:一级缓存(本地)和二级缓存(全局)
1、默认情况下,只有一级缓存( SqlSession级别的缓存也称为本地缓存)开启。
2、二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
3、为了提高扩展性。MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

1. 基础环境

1.1 数据库准备

USE mybatis;
# 创建一个名称为tb_book的表
CREATE TABLE  tb_book( id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(255),price double,author VARCHAR(40)
);
# 插入3条数据
INSERT INTO tb_book(name,price,author) VALUES('Java基础入门',45.0,'Liy');
INSERT INTO tb_book(name,price,author) VALUES('Java基础案例教程',48.0,'Tom');
INSERT INTO tb_book(name,price,author) VALUES('JavaWeb程序设计任务教程',50.0,'Jack');

1.2 Idea环境搭建

1.2.1 创建一个cache的module

1.2.2 在pom.xml中引入所需要的包

mybatis, mysql-connector-java, junit, log4j, lombok

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>mybatis-series</artifactId><groupId>com.biem</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cache</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.16</version></dependency></dependencies>
</project>

1.2.3 创建包:com.biem.pojo, com.biem.mapper, com.biem.util

1.2.4 在resource下添加配置文件

1.2.4.1 添加配置文件jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
jdbc.username=root
jdbc.password=root

1.2.4.2 添加配置文件log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"><appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"><param name="Encoding" value="UTF-8"/><layout class="org.apache.log4j.PatternLayout"><param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n"/></layout></appender><logger name="java.sql"><level value="debug"/></logger><logger name="org.apache.ibatis"><level value="info"/></logger><root><level value="debug"/><appender-ref ref="STDOUT"/></root>
</log4j:configuration>

1.2.4.3 添加MyBatis的核心配置类mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--引入properties文件--><properties resource="jdbc.properties"></properties><!--将下划线映射为驼峰--><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings><!--设置类型别名--><typeAliases><package name="com.biem.pojo"/></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><!-- 引入映射文件 --><mappers><package name="com.biem.mapper"/></mappers></configuration>

1.2.4.4 创建映射文件所在的目录

1.2.5 添加工具类com.biem.util.MyBatisUtil.java

package com.biem.util;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 java.io.IOException;
import java.io.InputStream;/*** ClassName: MybatisUtil* Package: com.biem.util* Description:** @Create 2023/4/5 22:23* @Version 1.0*/
public class MyBatisUtil {//利用static(静态)属于类不属于对象,且全局唯一private static SqlSessionFactory sqlSessionFactory = null;//利用静态块在初始化类时实例化sqlSessionFactorystatic {InputStream is= null;try {is = Resources.getResourceAsStream("mybatis-config.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);} catch (IOException e) {e.printStackTrace();throw new ExceptionInInitializerError(e);}}/*** openSession 创建一个新的SqlSession对象* @return SqlSession对象*/public static SqlSession openSession(boolean autoCommit){return sqlSessionFactory.openSession(autoCommit);}public static SqlSession openSession(){return sqlSessionFactory.openSession();}/*** 释放一个有效的SqlSession对象* @param session 准备释放SqlSession对象*/public static void closeSession(SqlSession session){if(session != null){session.close();}}
}

1.2.6 实体类com.biem.pojo.Book.java

package com.biem.pojo;import lombok.*;/*** ClassName: Book* Package: com.biem.pojo* Description:** @Create 2023/5/18 7:58* @Version 1.0*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Book {private Integer id;private String name;private Integer price;private String author;
}

1.2.7 mapper接口

package com.biem.mapper;/*** ClassName: BookMapper* Package: com.biem.mapper* Description:** @Create 2023/5/18 8:01* @Version 1.0*/
public interface BookMapper {}

1.2.7 mapper映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.biem.mapper.BookMapper"><!-- sql语句要和接口的方法名保持一致 --></mapper>

2. 一级缓存(本地)

MyBatis的一级缓存是SqlSession级别的缓存。
如果同一个SqlSession对象多次执行完全相同的SQL语句,在第一次执行完成后,MyBatis会将查询的结果写入到一级缓存中。此后如果程序没有执行插入、更新、删除操作。当第二次执行相同的查询语句时,MyBatis会直接读取一级缓存中的数据,而不在去数据库查询,从而提高了数据库的查询效率。
测试案例1:
从数据库tb_book查询id为1的图书信息的时候,当第一次查询后会将结果写入MyBatis的一级缓存,当程序第二次查询id为1的图书信息,MyBatis会直接从一级缓存中读取。

2.1 接口添加方法

package com.biem.mapper;import com.biem.pojo.Book;public interface BookMapper {public Book findBookById(Integer id);
}

2.2 映射文件添加实现

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.biem.mapper.BookMapper"><!-- sql语句要和接口的方法名保持一致 --><!--public Book findBookById(Integer id);--><select id="findBookById" parameterType="Integer" resultType="Book">select * from tb_book where id=#{id}</select>
</mapper>

2.3 测试方法

package com.biem.test;import com.biem.mapper.BookMapper;
import com.biem.pojo.Book;
import com.biem.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;/*** ClassName: UserTest* Package: com.biem.test* Description:** @Create 2023/5/18 8:44* @Version 1.0*/
public class UserTest {@Testpublic void findBookById(){SqlSession session = MyBatisUtil.openSession();BookMapper mapper = session.getMapper(BookMapper.class);Book book = mapper.findBookById(1);System.out.println("book = " + book);session.close();}@Testpublic void testCache1(){SqlSession session = MyBatisUtil.openSession();BookMapper mapper1 = session.getMapper(BookMapper.class);Book book1 = mapper1.findBookById(1);System.out.println("book1 = " + book1);BookMapper mapper2 = session.getMapper(BookMapper.class);Book book2 = mapper2.findBookById(1);System.out.println("book1 = " + book2);session.close();}
}

2.4 结果分析

findBookById输出如下:

DEBUG 05-18 09:07:47,909 ==>  Preparing: select * from tb_book where id=? (BaseJdbcLogger.java:137)
DEBUG 05-18 09:07:47,986 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137)
DEBUG 05-18 09:07:48,047 <==      Total: 1 (BaseJdbcLogger.java:137)
book = Book(id=1, name=Java基础入门, price=45, author=Liy)

testCache1输出如下

DEBUG 05-18 09:07:48,056 ==>  Preparing: select * from tb_book where id=? (BaseJdbcLogger.java:137)
DEBUG 05-18 09:07:48,057 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137)
DEBUG 05-18 09:07:48,059 <==      Total: 1 (BaseJdbcLogger.java:137)
book1 = Book(id=1, name=Java基础入门, price=45, author=Liy)
book1 = Book(id=1, name=Java基础入门, price=45, author=Liy)

从上述输出可以看出testCache1只是查询了一次,第二次查询的时候并没有连接数据库
testCache1fail输出如下

DEBUG 05-18 09:14:30,875 ==>  Preparing: select * from tb_book where id=? (BaseJdbcLogger.java:137)
DEBUG 05-18 09:14:30,953 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137)
DEBUG 05-18 09:14:31,015 <==      Total: 1 (BaseJdbcLogger.java:137)
book1 = Book(id=1, name=Java基础入门, price=45, author=Liy)
DEBUG 05-18 09:14:31,059 ==>  Preparing: select * from tb_book where id=? (BaseJdbcLogger.java:137)
DEBUG 05-18 09:14:31,060 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137)
DEBUG 05-18 09:14:31,065 <==      Total: 1 (BaseJdbcLogger.java:137)
book1 = Book(id=1, name=Java基础入门, price=45, author=Liy)

3. 二级缓存(全局)

3.1 开启缓存前配置

3.1.1 实体类实现Serializable 接口

package com.biem.pojo;import lombok.*;import java.io.Serializable;@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Book implements Serializable {private Integer id;private String name;private Integer price;private String author;
}

3.1.2 mybatis-config.xml中开启二级缓存全局配置

mybatis-config.xml中添加

    <settings><setting name="cacheEnabled" value="true"/></settings>

3.1.3 开启当前mapper下的二级缓存BookMapper.xml

BookMapper.xml添加

<cache></cache>

3.2 添加测试方法UserTest.java

    @Testpublic void testCache2_0(){SqlSession session1 = MyBatisUtil.openSession();BookMapper mapper1 = session1.getMapper(BookMapper.class);Book book1 = mapper1.findBookById(1);System.out.println("book1 = " + book1);SqlSession session2 = MyBatisUtil.openSession();BookMapper mapper2 = session2.getMapper(BookMapper.class);Book book2 = mapper2.findBookById(1);System.out.println("book1 = " + book2);session1.close();session2.close();}@Testpublic void testCache2_1(){SqlSession session1 = MyBatisUtil.openSession();BookMapper mapper1 = session1.getMapper(BookMapper.class);Book book1 = mapper1.findBookById(1);System.out.println("book1 = " + book1);session1.close();SqlSession session2 = MyBatisUtil.openSession();BookMapper mapper2 = session2.getMapper(BookMapper.class);Book book2 = mapper2.findBookById(1);System.out.println("book1 = " + book2);session2.close();}

3.3结果分析

testCache2_1进行了一次查询,结果如下:

DEBUG 05-18 09:40:00,228 Cache Hit Ratio [com.biem.mapper.BookMapper]: 0.0 (LoggingCache.java:60)
DEBUG 05-18 09:40:02,793 ==>  Preparing: select * from tb_book where id=? (BaseJdbcLogger.java:137)
DEBUG 05-18 09:40:02,867 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137)
DEBUG 05-18 09:40:02,944 <==      Total: 1 (BaseJdbcLogger.java:137)
book1 = Book(id=1, name=Java基础入门, price=45, author=Liy)
WARN  05-18 09:40:02,960 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 05-18 09:40:02,968 Cache Hit Ratio [com.biem.mapper.BookMapper]: 0.5 (LoggingCache.java:60)
book1 = Book(id=1, name=Java基础入门, price=45, author=Liy)

testCache2_2进行了一次查询,结果如下:

DEBUG 05-18 09:41:38,669 Cache Hit Ratio [com.biem.mapper.BookMapper]: 0.0 (LoggingCache.java:60)
DEBUG 05-18 09:41:41,356 ==>  Preparing: select * from tb_book where id=? (BaseJdbcLogger.java:137)
DEBUG 05-18 09:41:41,433 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137)
DEBUG 05-18 09:41:41,504 <==      Total: 1 (BaseJdbcLogger.java:137)
book1 = Book(id=1, name=Java基础入门, price=45, author=Liy)
WARN  05-18 09:41:41,523 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 05-18 09:41:41,529 Cache Hit Ratio [com.biem.mapper.BookMapper]: 0.5 (LoggingCache.java:60)
book2 = Book(id=1, name=Java基础入门, price=45, author=Liy)
DEBUG 05-18 09:41:41,531 Cache Hit Ratio [com.biem.mapper.BookMapper]: 0.6666666666666666 (LoggingCache.java:60)
book3 = Book(id=1, name=Java基础入门, price=45, author=Liy)

testCache2_0和testCache1一样的内容,输出结果如下:

DEBUG 05-18 09:39:11,470 Cache Hit Ratio [com.biem.mapper.BookMapper]: 0.0 (LoggingCache.java:60)
DEBUG 05-18 09:39:14,368 ==>  Preparing: select * from tb_book where id=? (BaseJdbcLogger.java:137)
DEBUG 05-18 09:39:14,501 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137)
DEBUG 05-18 09:39:14,567 <==      Total: 1 (BaseJdbcLogger.java:137)
book1 = Book(id=1, name=Java基础入门, price=45, author=Liy)
DEBUG 05-18 09:39:14,580 Cache Hit Ratio [com.biem.mapper.BookMapper]: 0.0 (LoggingCache.java:60)
DEBUG 05-18 09:39:14,656 ==>  Preparing: select * from tb_book where id=? (BaseJdbcLogger.java:137)
DEBUG 05-18 09:39:14,656 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137)
DEBUG 05-18 09:39:14,659 <==      Total: 1 (BaseJdbcLogger.java:137)
book1 = Book(id=1, name=Java基础入门, price=45, author=Liy)

testCache2_0依然进行了两次查询,session.close()执行之前并没有刷新缓存。

备注:如果使用annotation方式,仅需要在***Mapper.class上添加@CacheNamespace(blocking = true)

MyBatis之缓存机制相关推荐

  1. MyBatis的缓存机制详解

    MyBatis的缓存机制详解 MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制,缓存可以极大的提升查询效率.MyBatis中默认定义了两级缓存,分别是一级缓存和二级缓存. ( ...

  2. MyBatis:缓存机制详解

    本篇内容包括:MyBatis 缓存机制概述.一级缓存与二级缓存的介绍.配置和具体流程. 一.MyBatis 缓存机制概述 在我们常见的 OLTP(on-line transaction process ...

  3. mybatis的缓存机制是怎么样的?

    正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持. 1.缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 ...

  4. Hibernate和MyBatis的缓存机制和比较

    原文地址:https://my.oschina.NET/u/1445731/blog/416200?p=%7B%7BtotalPage%7D%7D Mybatis缓存 分为1级缓存和2级缓存,2级缓存 ...

  5. 11【MyBatis的缓存机制】

    文章目录 二.Mybatis缓存机制 2.1 缓存介绍 2.2 一级缓存 2.2.1 一级缓存相关参数 2.2.2 一级缓存测试 2.2.3 一级缓存清空 2.2.3.1 设置localCacheSc ...

  6. (十二)Mybatis的缓存机制

    文章目录 环境 Mybatis的缓存 一级缓存 一级缓存失效 方式一 方式二 二级缓存 MyBatis集成EhCache缓存 Mybatis学习目录 上一篇:(十一)MyBatis的高级映射及延迟加载 ...

  7. mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache

    1      查询缓存 1.1  什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在 ...

  8. 框架:mybatis的缓存机制

    一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据.不同的sqlSession之间的缓存数 ...

  9. Mybatis的缓存机制Cache

    Mybatis提供对缓存的支持,分为一级缓存和二级缓存,在没有配置的情况下,系统默认会使用一级缓存. 一级缓存(SqlSession级别) 我们都知道每个SqlSession对象之间的缓存是互不影响的 ...

最新文章

  1. AES加密_ js与C#互通
  2. Apache Ignite(五):Ignite的集群部署
  3. MySQL事务的回滚
  4. 利用协议代理实现导航控制器UINavigationController视图之间的正向传值和反向传值...
  5. Java容器的遍历之增强for循环
  6. 有状态的bean和无状态的bean的区别
  7. CCF NOI1029 信息加密
  8. 四剑客查找字符_linux 四剑客 find 、grep、sed、awk整理
  9. Windows11安装WSA教程android子系统安装方法(22000+dev) Msixbundle(1.2GB) 安装包下载
  10. 乐吾乐Topology-le5le为智慧电力可视化赋能(一)
  11. 类抽屉问题的C++解决
  12. 恶意软件家族分类 单模型方案总结
  13. 逻辑右移、算术右移与循环逻辑右移
  14. 单片机cant通讯 c语言,基于C8051F040单片机的CAN总线通信
  15. 高纯度高活性艾美捷人重组MEGACD40L蛋白(可溶性)
  16. Foxmail提示错误421 too many connections【企业邮箱申请】
  17. 技巧1——怎样查看linux发行版本名称和版本号?
  18. 红米5a手机html查看器,红米5A如何截图 红米5A手机截图方法【详细介绍】
  19. 阿里云ecs服务器挂载oss
  20. 微信 android 闪退问题怎么解决方法,如何解决微信闪退问题 四种解决微信闪退无法登录的原因及方法分享...

热门文章

  1. 查找算法【二叉查找树】 - 二叉查找树的删除
  2. DS3231时钟芯片IIC地址
  3. 简述计算机辅助设计工作过程,选矿厂计算机辅助设计作业.doc
  4. 基于PyQt5的快速开发模板系统-Excle数据批量导入及导出表格数据为Excle
  5. 微信小程序开发学习—Day3
  6. 向量内积(点乘)和外积(叉乘)概念及几何意义
  7. 微信小程序手机号解密报错:pad block corrupted 解决方法
  8. 点云粗配准4PCS及相应变种+在R稠密三维重建场景中的应用效果
  9. javaScript 对象添加属性和创建js对象的方式(以及理解:“无法给构造函数添加新的属性“)
  10. 龙越管道 参编《家居装饰装修技术规范和验收标准》