文章目录
什么是缓存
程序经常要调用的对象存在内存中,方便其使用时可以快速调用,不必去数据库或者其他持久化设备中查询,主要就是提⾼性能
包括:DNS缓存、前端缓存、代理服务器缓存Nginx、应用程序缓存(本地缓存、分布式缓存)、数据库缓存
分布式缓存
与应用分离的缓存组件或服务,与本地应用隔离⼀个独立的应用,多个应⽤可直接的共享缓存常见的分布式缓存 Redis、Memcached等
本地缓存
和业务程序⼀起的缓存,例如myabtis的⼀级或者⼆级缓存,本地缓存自然是最快的,但是不能在多个节点共享
常见的本地缓存:ssm基础课程myabtis ⼀级缓存、mybatis⼆级缓存;框架本身的缓存;redis本地单机服务;ehchche;guava cache、Caffeine等
谷歌开源缓存框架Guava Cache
引入依赖
<!--guava依赖包-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
封装类
@Component
public class BaseCache {
private Cache<String,Object> tenMinuteCache = CacheBuilder.newBuilder()
//设置缓存初始⼤⼩,应该合理设置,后续会扩容
.initialCapacity(10)
//最⼤值
.maximumSize(100)
//并发数设置
.concurrencyLevel(5)
//缓存写输入时间,写⼊后10分钟过期
.expireAfterWrite(600, TimeUnit.SECONDS)
//统计缓存命中率
.recordStats()
.build();
}
使用Guava缓存
缓存key管理类
public class CacheKeyManager {
/**
* 首页视频列表缓存key
*/
public static final String INDEX_VIDEL_LIST = "index:video:list";
}
在xxxServiceImpl类中使用
@Override
public List<Video> listVideo() {
try{
//使用Lambda表达式在缓存的位置(缓存key管理类设置的)找是否有数据,没有去查数据库,存在缓存里
Object cacheObj = baseCache.getTenMinuteCache().get(CacheKeyManager.INDEX_VIDEL_LIST,()->{
List<Video> videoList = videoMapper.listVideo();
System.out.println("从数据库里面找视频列表");
return videoList;
});
if(cacheObj instanceof List){
List<Video> videoList = (List<Video>)cacheObj;
return videoList;
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
测试
第一次访问,guava缓存中没有,查数据库:
第二次访问,guava中有,控制台不打印信息
当方法中有传参时
缓存key管理类设置中使用%s代替参数
public static final String VIDEO_DETAIL = "video:detail:%s";
xxxServiceImpl类中先声明字符串Key,拼接参数
String videoCacheKey = String.format(CacheKeyManager.VIDEO_DETAIL,videoid);