介绍:缓存的填充方式有三种,手动、同步和异步
手动控制缓存的增删改处理,主动增加、获取以及依据函数式更新缓存,底层使用ConcurrentHashMap进行节点存储,因此get方法是安全的。批量查找可以使getAllPresent()方法或者带填充默认值的getAll()方法
LoadingCache对象进行缓存的操作,使用CacheLoader进行缓存存储管理。 批量查找可以使用getAll()方法。 默认情况下, getAll()将会对缓存中没有值的key分别调用CacheLoader.load方法来构建缓存的值(build中的表达式)。我们可以重写CacheLoader.loadAll方法来提高getAll()的效率。
AsyncLoadingCache对象进行缓存管理,get()返回一个CompletableFuture对象,默认使用ForkJoinPool.commonPool()来执行异步线程,但是我们可以通过Caffeine.executor(Executor) 方法来替换线程池
介绍:
Caffeine的缓存清除是惰性的,可能发生在读请求后或者写请求后 比如说有一条数据过期后,不会立即删除,可能在下一次读/写操作后触发删除(类比于redis的惰性删除)。 如果读请求和写请求比较少,但想要尽快的删掉cache中过期的数据的话, 可以通过增加定时器的方法,定时执行cache.cleanUp()方法(异步方法,可以等待执行),触发缓存清除操作。
通过权重来计算,每个实体都有不同的权重,总权重到达最高时淘汰实体。 weigher()方法可以指定缓存所占比重,maximumWeight()方法指定最大的权重阈值,当添加缓存超过规定权重后,进行数据淘汰
expireAfterAccess():缓存访问后,一定时间失效;即最后一次访问或者写入开始时计时。 expireAfterWrite():缓存写入后,一定时间失效;以写入缓存操作为准计时。(在最后一次写入缓存后开始计时,在指定的时间后过期。) expireAfter():自定义缓存策略,满足多样化的过期时间要求。 这里只展示after, 其他的话 使用方式大致相同,自己动手试试 注意:当expireAfterAccess和expireAfterWrite同时存在时,只有expireAfterWrite有效
refreshAfterWrite:这里设置的是1分钟后自动刷新
1、缓存配置类
@Configuration public class CacheConfig { @Bean public Cache<String, Object> caffeineCache() { return Caffeine.newBuilder() // 设置最后一次写入或访问后经过固定时间过期 .expireAfterWrite(60, TimeUnit.SECONDS) // 初始的缓存空间大小 .initialCapacity(100) // 缓存的最大条数 .maximumSize(1000) .build(); } }2、使用 注意:这里我只写了存入的写法, 如果要获取缓存,用cache的get缓存我们存储的key就可以了。 如:
// 以下代码的具体含义请看文章, 文章都有介绍,如果没有 可以评论 我会给你进行解答 cache.put(1,"测试缓存") // 获取缓存 cache.get("1"); // 如果你使用get爆红, 那可能是因为你没有填写第二个,那么你可以这样做 cache.get("1", value -> value); // 或者 cache.asMap().get("1");示例:
private final Cache<Object, Object> cache; public FeedbackServiceImpl( Cache<Object, Object> cache) { this.cache = cache; } public void insertFeedBack(Feedback feedback) { int i = feedbackMapper.insert(feedback); cache.put(feedback.getId(), feedback); }注意:如果你只是简单的使用, 你可以使用末文的缓存工具类
示例:
// 开启缓存 @EnableCaching public class Springboot01CacheApplication { public static void main(String[] args) { SpringApplication.run(Springboot01CacheApplication.class, args); } } // 其他方法使用和他一样, 具体可以看代码,来自己动动手试试看 @Cacheable(cacheNames = {"emp"},condition = "#id>0") public Employee getEmp(Integer id){ System.out.println("查询"+id+"号员工"); Employee emp = employeeMapper.getEmpById(id); return emp; }具体含义看代码注释
/** * @author huangye 所谓致知在格物者,言欲致吾之知,在即物而穷其理也。 * @version 1.0 2020/10/4 */ public class CacheUtil{ private static Cache<String, Object> cache; static { cache = createCache(); } /** * 插入缓存 | 更新缓存 * @param cacheName 缓存前缀 * @param key 键 * @param value 值 */ public static void saveCache(String cacheName, String key, Object value) { System.out.printf("存储缓存的数据 key(%s) value(%s)",cacheName + "-" + key, value); System.out.println(); cache.asMap().put(cacheName + "-" + key, value); } /** * 根据键获取缓存 * @param cacheName 缓存前缀 * @param key 键 * @return Object类型, 由使用者自己转换 */ public static Object getCache(String cacheName, String key) { System.out.printf("获取缓存的数据 key(%s) value(%s)",cacheName + "-" + key, cache.asMap().get(cacheName + "-" + key) ); System.out.println(); return cache.asMap().get(cacheName + "-" + key); } /** * 根据键值删除缓存 * @param cacheName 缓存前缀 * @param key 建 */ public static void deleteCache(String cacheName, String key) { System.out.printf("删除缓存的数据 key(%s)", cacheName + "-" + key); System.out.println(); cache.asMap().remove(cacheName + "-" + key); } private static class CacheSingletonHolder { private final static Cache<String, Object> CACHE = Caffeine.newBuilder() // 初始的缓存空间大小 .initialCapacity(100) // 缓存的最大条数 .maximumSize(1000) // 最后一次缓存访问过后,7天后失效 .expireAfterAccess(7, TimeUnit.DAYS) .build(); } private static Cache<String, Object> createCache() { return CacheSingletonHolder.CACHE; } }ps:这里的图片都来源于我学习时做的笔记(下图位证), 因为有的是在网上找文章学习的,所以可能会遇到有的是和别人一样的内容,我是想着吧那些之前看的文章放到文章末尾的,但是我找不到了非常抱歉, 我这里的话只是想做个知识的汇总,如果有错误的地方,可以评论留言 我会改正,谢谢