前言:干货记录学习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. ANSI C说明了三个用于存储空间动态分配的函数

    1.1 malloc的全称是memory allocation,中文叫动态内存分配.原型:extern void *malloc(unsigned int num_bytes);说明:分配长度为num ...

  2. SSM整合二

    总结 <!-- 批量删除 --> <delete id="deleteAll"> delete from tbl_emp where emp_id in & ...

  3. rocketmq知识点

    消息队列mq 参考资料:https://www.jianshu.com/p/824066d70da8 一.消息中间件的主要作用和功能: 1)异步解耦和分流: 2)挡住前端的数据洪峰,保证后端系统的稳定 ...

  4. 辗转相除 求最大公约数!or 最小公倍数

    求最大公约数和最小公倍数的经典算法--辗转相除法描述如下: 若要求a,b两数的最大公约数和最小公倍数,令a为a.b中较大数,b为较小数,算法进一步流程: while(b不为0) { temp=a%b: ...

  5. Android:绘制字符

    根据FontMetrics的特点,将字符在矩形框中居中显示:

  6. easycode一键生成

  7. 【WPF】 OxyPlot图表控件学习

    最近在学习OxyPlot图表控件,一些基本的学习心得,在这里记录一下,方便以后进行查找.   一.引用 OxyPlot控件可以直接在VS的 " Nuget " 里面下载   选择: ...

  8. 如何获取 Android CPU 核心数 (Java/C++)

    1 前言 最近学习Power HAL方面相关知识,透过Power HAL 去配置CPU的Freq需要先确定 CPU 核数.便先了解如何获取 Android CPU 核数. 2 Java层获取方式 // ...

  9. 对 RESTful 的理解

    REST 全称 Representation State Transfor (资源表现层状态改变) 实际上是指客户端通过http/https协议手段来改变URI的状态转化,达到请求不同的资源的目的. ...

  10. Python - 文件模式a+读取不了文件

    代码 f = open('test/gbk.txt', 'a+', encoding='utf-8') print(f.readline()) 最终的执行结果是输出空,为什么呢? a+模式打开文件指针 ...