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.本地缓存不存在, ...
随机推荐
- FastReport.net 绿色破解版winform中使用
FastReport 是非常有名的报表库,曾经在delphi中经常看到 现在FastReport.net 是.net平台下的实现.它的价格对于个人开发者来说确实非常非常贵 出于学习的目的(0<& ...
- Python打印图片
准备好图片:(我女票) python代码: # by gubin 6.20 from dyy from PIL import Image import sys import os def _main( ...
- DQL,DML,DDL,DCL分别是什么?
SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL. 数据查询语言DQL数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHERE子句 ...
- Verilog实例数组
编写 Verilog 代码多年,至今才无意中发现了一种奇怪的语法,估计见过的这种的写法的人,在 FPGA 开发者中不会超过 20% 吧. 直接来看代码吧.先定义了一个简单的模块,名为 mod. mod ...
- IPython中也要保持优雅(DRY原则)
What is IPython? IPython provides a rich architecture for interactive computing with: A powerful int ...
- 高德地图——2D转换3D
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script ty ...
- Centos7部署Open-falcon 0.2.0
官方和github上都有教程,但是对于我来说有的部署内容较为陌生,有点错误官方也未在教程中说明,故在此记录方便以后快速部署,本文部署的时间是2018/10/10. 虽然open-falcon是采用了前 ...
- vue-父子组件之传值和单项数据流问题
前言 我们知道 vue 中父子组件的核心概念是单项数据流问题,props 是单项传递的.那究竟什么是单项数据流问题,这篇文章来总结一下关于这个知识点的学习笔记. 正文 1.父组件传值给子组件 < ...
- vue JS获取当前时间并格式化 ( 前端小细节,大进步 )
JS // 获取并且格式化时间 formatter (thistime, fmt) { let $this = new Date(thistime) let o = { ...
- Mybatis(三)——全局配置文件
二.properties 三.settings 四.typeAilases 这里不做介绍.