mybatis的一级缓存和二级缓存

一、介绍

1、mybatis缓存:

 mybatis包含一个非常强大的查询缓存特性,可以非常方便的定制和配置缓存,通过缓存减少Java Application与数据库的交互次数,从而提升程序的运行效率。

2、mybatis一二级缓存

mybatis的缓存分为一级缓存和二级缓存。

(1)默认情况下一级缓存开启(sqlSession级别的缓存,也称本地缓存)

(2)二级缓存需要手动开启,映射器级别的缓存,针对不同的namespace的映射器。为了提高扩展性,Mybatis定义了缓存接口Cache,我们可以通过实现Cache接口来自定义二级缓存

3、工作流程

一级缓存是先去一级缓存区中查找数据,如果没有再去数据库中查找,找到数据后将数据存入一级缓存区;二级缓存是先去二级缓存区域找数据,没有的话再接着去一级缓存区找数据,如果再没有就去数据库里拿数据,拿到后将数据存入二级缓存区。

4、缓存的适应性
  • 经常查询并且不经常改变的
  • 数据的正确性对最终结果影响不大的

二、一级缓存

1、配置

一级缓存是SqlSession级别。一级缓存的作用域是 SqlSession , Mabits 默认开启一级缓存。 在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。 当执行SQL时候两次查询中间发生了增删改的操作,则SqlSession的缓存会被清空。一级缓存有两个级别可以设置:session级别和statement级别。默认是session级别。

(1) session级别

即在一个Mybatis会话中执行的所有语句都会共享这一个缓存。

<setting name="localCacheScope" value="session">
 (2)statement级别

可以理解为缓存只对当前执行的这一个statement有效。

<setting name="localCacheScope" value="statement">
2、存储原理

一级缓存 Mybatis的内部使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。 Sqlsession执行insert、update、delete等操作commit后会清空该SqlSession缓存。

3、工作流程

(1)对于某个Select Statement,根据该Statement生成key;
(2)判断在本地缓存(local cache)中,该key是否有对应的数据存在
(3)如果命中,则跳过查询数据库,拿到本地的数据,继续往下走。
(4)如果没命中,去数据库中查询数据,得到想要的结果
(5)将key和查询到的结果作为一个键值对存入本地缓存(local cache)中
(6)将查询结果返回
(7)判断缓存级别是否为Statement级别,如果是的话,清空本地缓存

4、demo

    

5、一级缓存失效场景

(1)不同sqlSession对应不同的一级缓存

如果场景了两个不同的sqlSession去查询同样的数据,缓存也会失效;

(2)同一个sqlSession的查询条件不同

(3)同一个sqlSession两次查询期间对数据进行了改变,(即增、删、改)

(4)同一个sqlSession两次查询期间手动清空了缓存

在两次查询之间调用了sqlSession的clearCache()方法清空了缓存,缓存自然也就失效了,第二次就要再去数据库里做查询取数据

三、二级缓存

二级缓存是Mapper级别的缓存,多个SqlSession去操作同一个Mapper中的sql语句,则这些SqlSession可以共享二级缓存,即二级缓存是跨SqlSession的。简单说就是同一个namespace 下的 mapper 映射文件中,用相同的sql去查询数据,会去对应的二级缓存内取结果。

下面看下开启mybatis二级缓存的几种方法:

1、mybatis开启本地二级缓存

以springboot项目为例

1.1、项目配置文件
# 开启二级缓存mybatis-plus.configuration.cache-enabled=true
1.2、mapper.xml

在需要开启的mapper.xml中,添加以下代码(在<mapper namespace>下方)

<!--开启二级缓存-->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
eviction可用的清除策略有:LRU – 最近最少使用:移除最长时间不被使用的对象。
FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
默认的清除策略是 LRU。flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。
1.3、mapper参数配置

(1)查询参数:

当为select查询语句时:

flushCache默认为false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存;

useCache默认为true,表示会将本条语句的结果进行二级缓存。

设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。所以:针对每次查询都需要最新的数据sql,要设置成useCache=false,禁用二级缓存。

 <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap" useCache="true">select <include refid="Base_Column_List" />from t_dm_custwhere id = #{id,jdbcType=BIGINT}</select>

(2)更新操作

当为insert、update、delete语句时:

flushCache默认为true,表示任何时候语句被调用,都会导致本地缓存和二级缓存被清空;

useCache属性在该情况下没有。

一般下执行完commit操作都需要刷新缓存,flushCache=true表示刷新缓存,这样可以避免数据库脏读。但是如果你不想刷新缓存只需要这么做:

 <update id="updateByPrimaryKey" parameterType="com.sl.domain.TDmCust" flushCache=false>update t_dm_custset create_time = #{createTime,jdbcType=TIMESTAMP}where id = #{id,jdbcType=BIGINT}</update>

最后,测试验证:

打开谷歌浏览器发送查询请求时可以看到控制台有sql打印出来。再用IE浏览器发送查询请求发现第二次未打出sql,说明第二次sql查询已经走了mybatis二级缓存。

2、使用redis开启二级缓存
2.1、pom:

 加上redis maven配置

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.2、配置文件
spring.redis.host=localhost
spring.redis.port=6379

因为这个类不是Spring管理的,所以通过MyBatisRedisSpringContext从ioc容器里获取redisTemplate类

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component
public class MyBatisRedisSpringContext implements ApplicationContextAware, DisposableBean {private static ApplicationContext applicationContext = null;@Overridepublic void destroy() throws Exception {}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {MyBatisRedisSpringContext.applicationContext = applicationContext;}public static ApplicationContext getApplicationContext() {return applicationContext;}public static <T> T getBean(String name) {return (T)applicationContext.getBean(name);}public static <T> T getBean(Class clz) {return (T)applicationContext.getBean(clz);}}
2.3、mapper文件配置
  <cache type="com.demo.cache.MybatisRedisCache" />

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/662971.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker中配置MySql环境

目录 一、简单安装 1. 首先从Docker Hub中拉取镜像 2. 启动尝试创建MySQL容器&#xff0c;并设置挂载卷。 3. 查看mysql8这个容器是否启动成功 4. 如果已经成功启动&#xff0c;进入容器中简单测试 4.1 进入容器 4.2 登录mysql中 4.3 进行简单添加查找测试 二、主从复…

MySQL-----初识

一 SQL的基本概述 基本概述 ▶SQL全称: Structured Query Language&#xff0c;是结构化查询语言&#xff0c;用于访问和处理数据库的标准的计算机语言。SQL语言1974年由Boyce和Chamberlin提出&#xff0c;并首先在IBM公司研制的关系数据库系统SystemR上实现。 ▶美国国家标…

MySQL亿级数据的查询优化-历史表该如何建

前端时间在知乎上看到一个问题&#xff0c;今天有空整理并测试了一下&#xff1a; 这个问题很具体&#xff0c;所以还是可以去尝试优化一下&#xff0c;我们基于InnoDB并使用自增主键来讲。 比较简单的做法是将历史数据存放到另一个表中&#xff0c;与最近的数据分开。那是不是…

如何使用Linux Archcraft结合内网穿透实现SSH远程连接

&#x1f4d1;前言 本文主要是使用Linux Archcraft结合内网穿透实现SSH远程连接的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#…

go gin 响应数据

go gin 响应数据 package mainimport ("fmt""github.com/gin-gonic/gin" )type UserInfo struct {UserName string json:"user_name"Age int json:"age"Password string json:"-" }func JsonTest(ctx *gin.Context…

黑马Java——常见API

一、游戏打包exe 游戏打包exe要考虑的因素&#xff1a; 游戏打包exe核心步骤&#xff1a; 详见《打包exe文档》 二、Math &#xff08;一&#xff09; Math类的常用方法 1、代码实现 2、小结

JVM 笔记

JVM HotSpot Java二进制字节码的运行环境 好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;具有垃圾回收功能数组下标越界检查多态&#xff08;虚方法表&#xff09; JVM组成 类加载子系统&#xff08;Java代码转换为字节码&#xff09;运行时数据…

【JavaEE进阶】 图书管理系统开发日记——贰

文章目录 &#x1f332;前言&#x1f384;设计数据库&#x1f343;引⼊MyBatis和MySQL驱动依赖&#x1f333;Model创建&#x1f38d;约定前后端交互接口&#x1f340;服务器代码&#x1f6a9;控制层&#x1f6a9;业务层&#x1f6a9;数据层 &#x1f334;效果展示⭕总结 &#…

01- k8s基础网络知识 之 underlay与overlay网络

前言&#xff1a; 我们在学习k8s网络之前&#xff0c;必须要了解k8s网络相关的一些基础知识&#xff0c;比如什么是underlay网络、overlay网络等&#xff0c;只有把基础知识掌握之后&#xff0c;后续学习k8s网络的时候&#xff0c;一些知识点就不会再云里雾里了。 1 underlay与…

协作办公开源神器:ONLYOFFICE

目录 前言ONLYOFFICE为什么选择ONLYOFFICE强大的文档编辑功能多种协作方式多人在线协同支持跨端多平台连接器安全性极高本地部署 ONLYOFFICE 8.0版本震撼来袭可填写的 PDF 表单显示协作用户头像更新插件界面设计更快更强大 总结 前言 近几年来&#xff0c;随着互联网技术的不断…

如何解决 docker registry x509 证书不信任问题?

最近想尝试一下极狐GitLab&#xff08;可以理解为 GitLab 在中国的发行版&#xff09;内置的容器镜像仓库&#xff0c;这样就不用自己安装 Harbor 之类的了。于是找了个服务器安装了一个极狐GitLab 的私有化部署版本&#xff0c;安装过程可以参考过往的技术文章使用Omnibus 安装…

在Windows搭建gRPC C++开发环境

本文介绍在Windows下使用Visual Studio 2017编译gRPC 1.48.0并配置开发环境&#xff0c;以及开发、配置一个简单的c服务端以及.net客户端。 0、前置条件 1、下载gRPC源码 使用git命令行在预备存放grpc源码的目录下执行, 此处我们下载的是 grpc 1.48.0 git clone -b v1.48.0 …

Pycharm python用matplotlib 3D绘图显示空白解决办法

问题原因&#xff1a; matplotlib版本升级之后显示代码变了&#xff0c;修改为新的 # ax Axes3D(fig) # 原代码 ax fig.add_axes(Axes3D(fig)) # 新代码import numpy as np import matplotlib.pyplot as plt from matplotlib import cm from mpl_toolkits.mplot3d import Ax…

测试环境搭建整套大数据系统(一:基础配置,修改hostname,hosts,免密,时间同步)

一&#xff1a;使用服务器配置。 二&#xff1a;修改服务器名称hostname&#xff0c;hosts。 在 Linux 系统中&#xff0c;hostname 和 /etc/hosts 文件分别用于管理主机名和主机名解析。 在三台服务器上&#xff0c;分别执行以下命令。 vim /etc/hostnamexdso-hadoop-test-0…

༺༽༾ཊ—Unity之-04-原型模式—ཏ༿༼༻

首先创建一个项目&#xff0c; 在这个初始界面我们需要做一些准备工作&#xff0c; 建基础通用文件夹&#xff0c; 创建一个Plane 重置后 缩放100倍 加一个颜色&#xff0c; 任务1&#xff1a;使用 建造者模式 创建三种 金刚猿猴 零部件 拼接组合 首先资源商店下载 金刚猿猴 模…

刨析数据结构(二)

&#x1f308;个人主页&#xff1a;小田爱学编程 &#x1f525; 系列专栏&#xff1a;数据结构————"带你无脑刨析" &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于数据结构的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎…

strlen函数详解

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;c语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&a…

动态微信小程序码和开发者工具解析小程序码

一、动态生成微信小程序码 1、方式一 微信官方网站&#xff0c;对已发布的小程序&#xff0c;提供了一个快捷的入口&#xff0c;输入微信小程序的page页面即可。 page页面可以通过右侧开启入口获取 也可以通过开发者工具左下角的页面地址和参数地址那里获取到 二、生成的小…

【软件设计师笔记】计算机系统基础知识考点

【考证须知】IT行业高含金量的证书(传送门) &#x1f496; 【软件设计师笔记】程序语言设计考点(传送门) &#x1f496; 【软件设计师笔记】操作系统考点(传送门) &#x1f496; &#x1f413; 计算机系统组成 计算机系统是由硬件和软件组成的&#xff0c;它们协同工作来运…

WAF 无法防护的八种风险

一、目录遍历漏洞 测试用例&#xff1a;Apache 目录遍历漏洞 测试环境搭建&#xff1a; apt intsall apache2 && cd /var/www/html/ && rm index.html无法拦截原因&#xff1a; 请求中无明显恶意特征&#xff0c;无法判断为攻击行为 实战数据&#xff1a; 截…