缓存工具类编写

缓存工具类编写

一般操作

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

java 复制代码
@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;
}

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

缓存工具类编写

java 复制代码
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;
    }
}

工具类的使用

java 复制代码
@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更换为把本地缓存),业务代码也不需要进行更改,只需要更改缓存工具类中的代码即可。

相关推荐
2601_9622972539 分钟前
python自带缓存lru_cache用法及扩展的使用_python
python·缓存·装饰器·lru_cache·my_cache
xixingzhe22 小时前
SpringBoot 接口缓存实现
spring boot·后端·缓存
莫得感情 o13 小时前
Redis 05 · 持久化:RDB 与 AOF 怎么保证数据不丢
redis·缓存
curd_boy14 小时前
【Redis】Redis从缓存到AI向量平台
人工智能·redis·缓存
kiracrimson14 小时前
从缓存的角度看链表与线性表的差异
数据结构·链表·缓存
2601_9623010118 小时前
深入理解缓存(Cache):原理、应用与优化
缓存·计算机原理·优化策略·数据访问·系统性能
数智启示录18 小时前
PostgreSQL 计划缓存实战(第 10 篇):预编译 SQL 前五次都快,第六次为什么可能变慢
经验分享·sql·缓存·postgresql·面试
跨境数据猎手1 天前
京东开放平台商品详情接口(jd.item_get):签名、缓存与批量采集
java·spring·缓存
xbgRS1 天前
Redis基本概念及应用
redis·缓存
草莓熊Lotso1 天前
【Redis 初阶】特殊数据类型、渐进式遍历与数据库操作生产指南
linux·网络·数据库·redis·tcp/ip·缓存·bootstrap