当前位置: 首页 > article >正文

缓存工具类编写

缓存工具类编写

一般操作

在外面日常开发中,经常会有为了减少数据库压力,而将数据保存到缓存中并设置一个过期时间的操作。日常代码如下:

@Autowired
private RedisTemplate<String, String> redisTemplate;

public Object queryDataWithCache(String id) {
    String cacheKey = "cacheKey:" + id;
    String value = redisTemplate.opsForValue().get(cacheKey);
    Object result = null;
    if (ObjectUtil.isNotEmpty(value)) { // 缓存中存在数据,直接返回
        result =  JsonUtil.getJsonToList(value, Object.class); // 将字符串转换为对应的类型
    } else { // 缓存中不存在数据,从数据库中查询
        result = queryFromDB(id); // 从数据库中查询数据
        String objectToString = JsonUtil.getObjectToString(result); // 将示例对象转换为json字符串
        redisTemplate.opsForValue().set(cacheKey, objectToString, 10L, TimeUnit.SECONDS); // 将数据保存到缓存中
    }
    return result;
}

通过代码可以发现,从缓存中取数据,和把数据保存缓存中的逻辑都是通用的,只有从数据库查询数据是不同的,我们可以把缓存操作抽取出来作为一个工具类使用,减少重复代码的编写。

缓存工具类编写

import cn.hutool.core.util.ObjectUtil;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import tbea.util.JsonUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * @Description 本地缓存工具类
 * @Author ZengXi
 * @Date 2024/11/19
 */
@Component
public class CacheUtils<V> 

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
    * @description: 获取数据
    * @author ZengXi
    * @date 2024/11/19
    * @param cacheKey 缓存的key
	* @param clazz 返回类型
	* @param function 查询数据库操作的函数
	* @param expireTime 缓存过期时间
    * @return V
    */
    public <V> V getResult(String cacheKey, Class<V> clazz, Supplier<V> function, int expireTime) {
        V result = null;
        String value = redisTemplate.opsForValue().get(cacheKey);
        if (ObjectUtil.isNotEmpty(value)) {
            result = JsonUtil.getJsonToBean(value, clazz);
        } else {
            result = function.get(); // 从数据库查询数据
            if (ObjectUtil.isNotEmpty(result)) {
                String objectToString = JsonUtil.getObjectToString(result);
                redisTemplate.opsForValue().set(cacheKey, objectToString, expireTime, TimeUnit.SECONDS);
            }
        }
        return result;
    }

    /**
    * @description: 获取数据列表
    * @author ZengXi
    * @date 2024/11/19
    * @param cacheKey 缓存的key
	* @param clazz 返回列表元素的类型
	* @param function 查询数据库操作的函数
	* @param expireTime 缓存过期时间
    * @return java.util.List<V>
    */
    public List<V> getResultList(String cacheKey, Class<V> clazz, Supplier<List<V>> function,
                                 int expireTime) {
        String value = redisTemplate.opsForValue().get(cacheKey);
        List<V> resultList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(value)) {
            resultList = JsonUtil.getJsonToList(value, clazz);
        } else {
            resultList = function.get(); // 从数据库查询数据
            if (ObjectUtil.isNotEmpty(resultList)) {
                String objectToString = JsonUtil.getObjectToString(resultList);
                redisTemplate.opsForValue().set(cacheKey, objectToString, expireTime, TimeUnit.SECONDS);
            }
        }
        return resultList;
    }
}

工具类的使用

@Autowired
private CacheUtils cacheUtils;

public Object queryDataWithCache(String id) {
    String cacheKey = "cacheKey:" + id;
    Object result = cacheUtils.getResult(cacheKey, Object.class, () -> queryFromDB(id), 10);
    return result;
}

总结

通过将查询数据库的函数作为传参,我们将缓存相关操作进行了抽取,减少了代码的编写,且如果后续需要更换缓存(如:将redis更换为把本地缓存),业务代码也不需要进行更改,只需要更改缓存工具类中的代码即可。


http://www.kler.cn/a/401166.html

相关文章:

  • 柔性仿人手指全覆盖磁皮肤,具备接触觉和运动觉的双模态感知能力
  • R语言基础入门详解
  • 【分布式技术】ES扩展知识-Elasticsearch分词器的知识与选择
  • 使用Python编写一个简单的网站爬虫,从网站上抓取新闻标题和链接。
  • STM32串口——5个串口的使用方法
  • c++数字雨实现
  • docker run怎么设置 entry point sleep?
  • 【AIGC】ChatGPT提示词Prompt解析:文章创作大师
  • EMNLP 2024 | 大语言模型的内部知识机理
  • 高效管理 SSH 免密码登录:多客户端与多服务器实践指南20241118
  • 鲸鱼机器人和乐高机器人的比较
  • 搭建vue-electron项目
  • 自动驾驶系统研发系列—智能驾驶核心功能:IHC如何提升夜间驾驶体验?
  • 数造科技亮相第26届高交会并接受媒体采访,以数据智能赋能未来
  • Oracle收缩表空间的简单方法
  • 每日OJ题_牛客_dd爱旋转_模拟_C++_Java
  • 数据结构 【单链表练习】
  • RPA真的是人工智能吗?
  • 二刷代码随想录第七天
  • git commit
  • 如何将几个音频合成一个音频?非常简单的几种合成方法
  • Pandas-5:数据分析与统计
  • MongoDB的常用命令(数据库操作、集合操作、文档操作)
  • CentOS 7.9 搭建本地Yum源
  • 汽车科技前沿:Spring Boot资讯快车道
  • 深入解析【C++多态】:探索面向对象编程中的动态绑定与行为多样性和多态的核心概念与应用实践