前言:干货记录学习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本地缓存&分布式缓存干货分享的更多相关文章

  1. springboot+mybatis+redis实现分布式缓存

    大家都知道springboot项目都是微服务部署,A服务和B服务分开部署,那么它们如何更新或者获取共有模块的缓存数据,或者给A服务做分布式集群负载,如何确保A服务的所有集群都能同步公共模块的缓存数据, ...

  2. 7.4mybatis整合ehcache(mybatis无法实现分布式缓存必须和其他缓存框架整合)

    <\mybatis\day02\14查询缓存-二级缓存-整合ehcache.av> mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache-- 这里有做本 ...

  3. WEB 应用缓存解析以及使用 Redis 实现分布式缓存

    什么是缓存? 缓存就是数据交换的缓冲区,用于临时存储数据(使用频繁的数据).当用户请求数据时,首先在缓存中寻找,如果找到了则直接返回.如果找不到,则去数据库中查找.缓存的本质就是用空间换时间,牺牲数据 ...

  4. mybatis系列-15-查询缓存

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

  5. MyBatis笔记——EhCache二级缓存

    介绍 ehcache是一个分布式缓存框架. 我们系统为了提高系统并发,性能.一般对系统进行分布式部署(集群部署方式)  不使用分布缓存,缓存的数据在各各服务单独存储,不方便系统开发.所以要使用分布式缓 ...

  6. 【MyBatis学习13】MyBatis中的二级缓存

    1. 二级缓存的原理 前面介绍了,mybatis中的二级缓存是mapper级别的缓存,值得注意的是,不同的mapper都有一个二级缓存,也就是说,不同的mapper之间的二级缓存是互不影响的.为了更加 ...

  7. 分布式进阶(十八) 分布式缓存之Memcached

    分布式缓存 分布式缓存出于如下考虑:首先是缓存本身的水平线性扩展问题,其次是缓存大并发下本身的性能问题,再次避免缓存的单点故障问题(多副本和副本一致性). 分布式缓存的核心技术包括首先是内存本身的管理 ...

  8. .Net Core 跨平台开发实战-服务器缓存:本地缓存、分布式缓存、自定义缓存

    .Net Core 跨平台开发实战-服务器缓存:本地缓存.分布式缓存.自定义缓存 1.概述 系统性能优化的第一步就是使用缓存!什么是缓存?缓存是一种效果,就是把数据结果存在某个介质中,下次直接重用.根 ...

  9. C#自由组合本地缓存、分布式缓存和数据库的数据

    一.背景介绍: 我们在进行数据存储的时候,有时候会加入本地缓存.分布式缓存以及数据库存储三级的结构,当我们取值的时候经常是像下面这样的流程: 1.先取本地缓存,如果值存在直接返回 2.本地缓存不存在, ...

随机推荐

  1. 异步编程之APM

    一.APM概述 APM即异步编程模型的简写(Asynchronous Programming Model),我们平时经常会遇到类似BeginXXX和EndXXX的方法,我们在使用这些方法的时候,其实就 ...

  2. Spring PropertyPlaceholderConfigurer 自定义扩展

    原文地址:https://blog.csdn.net/feiyu8607/article/details/8282893 Spring中PropertyPlaceholderConfigurer这个类 ...

  3. Redis常用技术

    Xml配置: <?xml version='1.0' encoding='UTF-8' ?> <!-- was: <?xml version="1.0" e ...

  4. 关于RandomAccess

    package special; import java.io.IOException; import java.io.RandomAccessFile; /** * 随机访问流: * * 此类不属于 ...

  5. Playwright-python 教程

    安装 pip install playwright -i https://mirrors.aliyun.com/pypi/simple/ 使用阿里源,下载速度快一点. python -m playwr ...

  6. pytorch 测试 迁移学习

    训练源码: 源码仓库:https://github.com/pytorch/tutorials 迁移学习测试代码:tutorials/beginner_source/transfer_learning ...

  7. 机器学习基本概念:batch_size、epoch、 iteration

    batch_size 单次训练用的样本数,通常为2^N,如32.64.128... 相对于正常数据集,如果过小,训练数据就收敛困难:过大,虽然相对处理速度加快,但所需内存容量增加. 使用中需要根据计算 ...

  8. Linux centos7 复制,移动,删除文件或文件夹

    2021-08-121. 文件(文件夹)复制命令 # 命令格式 cp [-adfilprsu] 源文件(source) 目标文件(destination) cp [option] source1 so ...

  9. netty系列之:搭建HTTP上传文件服务器

    目录 简介 GET方法上传数据 POST方法上传数据 POST方法上传文件 总结 简介 上一篇的文章中,我们讲到了如何从HTTP服务器中下载文件,和搭建下载文件服务器应该注意的问题,使用的GET方法. ...

  10. 第20篇-加载与存储指令之ldc与_fast_aldc指令(2)

    ldc指令将int.float.或者一个类.方法类型或方法句柄的符号引用.还可能是String型常量值从常量池中推送至栈顶. 这一篇介绍一个虚拟机规范中定义的一个字节码指令ldc,另外还有一个虚拟机内 ...