64 lines
2.0 KiB
Java
Raw Normal View History

package edu.whut.smilepicturebackend.manager.cache;
import cn.hutool.json.JSONUtil;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
@Service
@RequiredArgsConstructor
public class MyCacheManager {
/**
* 本地缓存
*/
private final Cache<String, String> localCache = Caffeine.newBuilder()
.initialCapacity(1024)
.maximumSize(10_000L) // 最大 10000 条
.expireAfterWrite(Duration.ofMinutes(5)) // 缓存 5 分钟后移除
.build();
/**
* 分布式缓存
*/
private final StringRedisTemplate stringRedisTemplate;
public <T> T getFromCacheOrDatabase(
String cacheKey,
Class<T> clazz,
Supplier<T> dbSupplier,
int redisExpireSeconds) {
// 查询本地缓存
String cachedValue = localCache.getIfPresent(cacheKey);
if (cachedValue != null) {
return JSONUtil.toBean(cachedValue, clazz);
}
// 查询 Redis 缓存
ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
cachedValue = opsForValue.get(cacheKey);
if (cachedValue != null) {
localCache.put(cacheKey, cachedValue);
return JSONUtil.toBean(cachedValue, clazz);
}
// 执行数据库查询
T dbValue = dbSupplier.get();
// 更新 Redis 缓存
cachedValue = JSONUtil.toJsonStr(dbValue);
opsForValue.set(cacheKey, cachedValue, redisExpireSeconds, TimeUnit.SECONDS);
// 写入本地缓存
localCache.put(cacheKey, cachedValue);
return dbValue;
}
}