public void set(String key, Object value, Long time, TimeUnit unit) {
stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonPrettyStr(value), time, unit);
}
/**
* 缓存穿透
* @param prefix
* @param id
* @param type
* @param dbFallback
* @param time
* @param unit
* @return
* @param <R>
* @param <ID>
*/
public <R,ID> R queryWithPassThrough(String prefix, ID id, Class<R> type, Function<ID,R> dbFallback,Long time, TimeUnit unit) {
//获取key
String key = prefix + id;
//从redis中获取信息
String json = stringRedisTemplate.opsForValue().get(key);
//如果有信息则直接把信息返回
if (StrUtil.isNotBlank(json)) {
return JSONUtil.toBean(json, type);
}
//如果信息存在但是不为空,则将redis中的”“值返回防止缓存穿透
if (json != null) {
return null;
}
//如果redis中没有,查询数据库,通过参数中传过来的方法
R r = dbFallback.apply(id);
//如果查不到信息,则向redis中传入一个短暂的”“防止缓存穿透
if (r == null) {
stringRedisTemplate.opsForValue().set(key, "", RedisConstants.CACHE_NULL_TTL, TimeUnit.MINUTES);
return null;
}
//如果查到了,则调用CacheClient类中的set方法,将数据缓存到redis中
this.set(key, r, time, unit);
return r;
}
缓存穿透和缓存击穿的区别是,缓存穿透是redis中和数据库中都差不到指定的信息,为了防止有人故意用不存在的id来攻击数据库,则在redis缓存中加入id:”null“值来进行回复,