目的
缓存降低耗时接口的结果, 重复查询时候可以减少时间消耗
例子代码
最近 <乘风破浪的姐姐们> 开播, 我作为一名资深宅男, 肯定不会放过这个综艺, 当我们想要查询根据 id 获取每个姐姐的信息的时候, 可能会比较耗时, 而这些信息基本不会变, 这时候就是缓存模式出场了.
缓存模式
定义一个查询:
public interface QueryAction<T, R> {
T queryFromCache(String key);
T query(R r);
void putToCache(String key, T t);
}
定义一个抽象的缓存实现:
public abstract class AbstractQueryAction<T, R> implements QueryAction<T, R> {
@Override
public T queryFromCache(String key) {
return (T) App.CACHE_MAP.get(key);
}
@Override
public void putToCache(String key, T t) {
App.CACHE_MAP.put(key, t);
}
}
定义一个模板:
public class CacheTemplate {
public <T, R> T queryByCaching(QueryAction<T, R> queryAction, R r, String key) {
T resultFromCahce = queryAction.queryFromCache(key);
if (resultFromCahce != null) {
return resultFromCahce;
}
T result = queryAction.query(r);
queryAction.putToCache(key, result);
return result;
}
}
这里有一个比较耗时的方法:
public class UserService {
@SneakyThrows
public static String queryUserName(String userId) {
Thread.sleep(1000);
if(Objects.equals("1",userId)) {
return "黄圣依";
}
if(Objects.equals("2",userId)) {
return "伊能静";
}
if(Objects.equals("3",userId)) {
return "张雨绮";
}
if(Objects.equals("4",userId)) {
return "宁静";
}
return "codog代码狗";
}
}
使用:
System.out.println(cacheTemplate.queryByCaching(new AbstractQueryAction<String, String>() {
@Override
public String query(String userId) {
return UserService.queryUserName(userId);
}
}, "123", "userid-123"));
课后作业
- 将抽象缓存类换成 redis 实现
- 思考如何保证缓存与接口的一致性
- 了解缓存雪崩, 缓存穿透, 缓存击穿, 并改进文中的代码
微信: