mybatis本地缓存&分布式缓存干货分享
前言:干货记录学习mybatis实际开发中缓存的使用。
环境: springboot2.X + mybatis3.x
Mybatis是一款持久层框架,它提供了一级缓存和二级缓存。
名词解释
- 一级缓存(mybatis默认开启)
同一个sqlSession中有效,在同一个SqlSession中,执行两次相同的sql查询,第二次不走数据库查询,而是在缓存中获取。 - 二级缓存(需要开发者自行添加代码开启)
二级缓存开启后,不同的sqlSession获取同一数据时,可以不走数据库查询直接从缓存中获取。
缓存原理:PerpetualCache 的 HashMap本地缓存
二级缓存的开启
<!--mybatise 配置文件中设置-->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!--某一个mapper中开启,mapper 配置文件中设置-->
<cache type="org.apache.ibatis.cache.impl.PerpetualCache" 具体执行缓存操作的类,mybatis默认PerpetualCache,我们可以自定义修改
blocking="false" (是否使用阻塞缓存): 默认为false,当指定为true时将采用BlockingCache进行封装,使用BlockingCache会在查询缓存时锁住对应的Key,如果缓存命中了则会释放对应的锁,否则会在查询数据库以后再释放锁这样可以阻止并发情况下多个线程同时查询数据.
eviction="LUR" 回收策略 默认 LUR 最近最少使用
flushInterval="" 缓存刷新时间间隔,单位毫秒,不设置则在调用时刷新
readOnly="true" 只读
size="1024" 缓存对象的个数 默认1024/>
<!-- 操作 CUD的 statement时候,会强制刷新二级缓存 -->
<!-- 我们可以指定 某一个 setect 操作 使用缓存或者不使用缓存 useCache 可以指定某一个 cud 操作 是否强制刷新缓存 flushCache -->
**注意:被缓存的对象可以被序列化和反序列化,就是实现实现Serializable接口**
使用redis替换mybatis自身的缓存实现(分布式缓存)
//功能简写了,使用时根据自己实际情况修改
public class MyRedisCache implements Cache {
private final String id; //当前放入缓存的Mapper的 namespace 名称空间
private final Map<Object, Object> cache = new HashMap<>();
public MyRedisCache(String id) {
this.id = id;
}
// 返回cache的唯一标识
@Override
public String getId() {
return id;
}
// 缓存放入值
// redis --- RedisTemplate StringRedisTemplate
@Override
public void putObject(Object key, Object value) {
getRedisTemplate().opsForHash().put(key,value);
}
// 从缓存中获取值
@Override
public Object getObject(Object key) {
return getRedisTemplate().opsForHash().get(key);
}
@Override
public void clear() {
//清空namespace
getRedisTemplate().delete(id.toString());//清空缓存
}
...
}
<!--使自定义的缓存执行类生效-->
<cache type="...MyRedisCache" .../>
自定义缓存执行类时注意的问题
- RedisTemplate对象是自动注入到IOC容器中,然后通过ApplicationContext对象回去容器对象。
在SpringBoot内部提供接口 ApplicationContextAware 获取IOC容器ApplicationContext对象。然后通过applicationContext对象获取Redis操作对象 RedisTemplate 对象。
@Configuration
public class ApplicationContextUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
//工厂中获取对象 工厂中RedisTemplate 默认 name redisTemplate
public static Object getBean(String beanName){
return applicationContext.getBean(beanName);
}
}
- 通过查看源码得到mybatis做缓存时使用的是Map,那么他的key的设计就很重要了,mybatis是使用mapper的 namespace 和sql做key,我们根据实际情况自己设计,存入redis的key的策略和合适的数据结构存储值(redis的数据结构后续更新)。我使用的是hash结构,redisTemplate.opsForHash().put(namespace,key,value);
最后
感谢您的阅读,各位大佬有什么意见和问题欢迎评论区留言!
觉得文章对你有帮助记得给我点个赞,欢迎大家关注和转发文章!
mybatis本地缓存&分布式缓存干货分享的更多相关文章
- springboot+mybatis+redis实现分布式缓存
大家都知道springboot项目都是微服务部署,A服务和B服务分开部署,那么它们如何更新或者获取共有模块的缓存数据,或者给A服务做分布式集群负载,如何确保A服务的所有集群都能同步公共模块的缓存数据, ...
- 7.4mybatis整合ehcache(mybatis无法实现分布式缓存必须和其他缓存框架整合)
<\mybatis\day02\14查询缓存-二级缓存-整合ehcache.av> mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache-- 这里有做本 ...
- WEB 应用缓存解析以及使用 Redis 实现分布式缓存
什么是缓存? 缓存就是数据交换的缓冲区,用于临时存储数据(使用频繁的数据).当用户请求数据时,首先在缓存中寻找,如果找到了则直接返回.如果找不到,则去数据库中查找.缓存的本质就是用空间换时间,牺牲数据 ...
- mybatis系列-15-查询缓存
15.1 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要 ...
- MyBatis笔记——EhCache二级缓存
介绍 ehcache是一个分布式缓存框架. 我们系统为了提高系统并发,性能.一般对系统进行分布式部署(集群部署方式) 不使用分布缓存,缓存的数据在各各服务单独存储,不方便系统开发.所以要使用分布式缓 ...
- 【MyBatis学习13】MyBatis中的二级缓存
1. 二级缓存的原理 前面介绍了,mybatis中的二级缓存是mapper级别的缓存,值得注意的是,不同的mapper都有一个二级缓存,也就是说,不同的mapper之间的二级缓存是互不影响的.为了更加 ...
- 分布式进阶(十八) 分布式缓存之Memcached
分布式缓存 分布式缓存出于如下考虑:首先是缓存本身的水平线性扩展问题,其次是缓存大并发下本身的性能问题,再次避免缓存的单点故障问题(多副本和副本一致性). 分布式缓存的核心技术包括首先是内存本身的管理 ...
- .Net Core 跨平台开发实战-服务器缓存:本地缓存、分布式缓存、自定义缓存
.Net Core 跨平台开发实战-服务器缓存:本地缓存.分布式缓存.自定义缓存 1.概述 系统性能优化的第一步就是使用缓存!什么是缓存?缓存是一种效果,就是把数据结果存在某个介质中,下次直接重用.根 ...
- C#自由组合本地缓存、分布式缓存和数据库的数据
一.背景介绍: 我们在进行数据存储的时候,有时候会加入本地缓存.分布式缓存以及数据库存储三级的结构,当我们取值的时候经常是像下面这样的流程: 1.先取本地缓存,如果值存在直接返回 2.本地缓存不存在, ...
随机推荐
- 【springcloud alibaba】注册中心之nacos
1.为什么需要注册中心 1.1 没有注册中心会怎么样 1.2 注册中心提供什么功能以及解决什么问题 2.常用的微服务注册中心对比 3.案例项目父工程 4.nacos作为注册中心的使用 4.1 单机版的 ...
- 【java虚拟机】Java内存模型
作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/7518259.html 一.什么是Java内存模型 Java虚拟机规范中试图定义一种Java内存模型(Jav ...
- Semaphore 的使用思路
转自:https://www.cnblogs.com/klbc/p/9500947.html 最近在看一本书<Java并发编程 核心方法与框架>,打算一边学习一边把学习的经验记下来,所粘贴 ...
- 求字符串长度之递归与非递归的C语言实现
在上一篇中介绍了字符串拷贝的递归与非递归的实现,这里就不在赘述递归原理. 递归求字符串长度_strlen: 1 int _strlen(const char *src) 2 { 3 if( src = ...
- servlet中servletContext的五大作用(四)
1. 获取web的上下文路径 2. 获取全局的参数 3. 作为域对象使用 4. 请求转发 5. 读取web项目的资源文件 package day10.about_serv ...
- 轻松搞定webpack5.x
源码地址:https://gitee.com/cyp926/webpack-project.git "webpack": "^5.46.0", "we ...
- C# - 习题07_计算1分2分5分硬币各有多少枚
时间:2017-09-08 整理:byzqy 题目:现在有1分.2分.5分硬币共100个,总金额为2.46元,请用程序计算出1分.2分.5分各有多少枚,有多少种算法? 这是最近面试遇到的一个题目,刚开 ...
- TensorFlow-Slim 简介+Demo
github介绍:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim 基于slim实现的yolo- ...
- 谷歌api 二维码生成 实例
谷歌提供的二维码生成器接口,非常实用!分享给大家 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...
- vue 之 v-model
v-model虽然很像使用了双向数据绑定的 Angular 的 ng-model,但是 Vue 是单项数据流,v-model 只是语法糖而已: <input v-model="sth& ...