阳光沙滩后端缓存第一页的做法是通过,在实体类判断之后缓存的。我们可以在这里进行注解的方式优化代码。我把重要的部分都做了注释,希望对大家有帮助。
@Override//原来的代码块
public ResponseResult listCommentByArticleId(String articleId, int page, int size) {
page = checkPage(page);
size = checkSize(size);
//如果是第一页,那我们先从缓存中获取
String cacheJson = (String) redisUtils.get(Constants.Comment.KEY_COMMENT_FIRST_PAGE_CACHE + articleId);
if (!TextUtils.isEmpty(cacheJson) && page == 1) {
PageList<Comment> result = gson.fromJson(cacheJson, new TypeToken<PageList<Comment>>() {
}.getType());
log.info("comment list from redis...");
return ResponseResult.SUCCESS("评论列表获取成功.").setData(result);
}
//如果就返回
//如果没有就往下走
Sort sort = new Sort(Sort.Direction.DESC, "state", "createTime");
Pageable pageable = PageRequest.of(page - 1, size, sort);
Page<Comment> all = commentDao.findAllByArticleId(articleId, pageable);
//把结果转成pageList
PageList<Comment> result = new PageList<>();
result.parsePage(all);
//保存一分到缓存里
if (page == 1) {
redisUtils.set(Constants.Comment.KEY_COMMENT_FIRST_PAGE_CACHE + articleId, gson.toJson(result), Constants.TimeValueInSecond.MIN_5);
}
return ResponseResult.SUCCESS("评论列表获取成功.").setData(result);
}
下边是注解的实现
@Target(ElementType.METHOD) //注解在方法中有效
@Retention(RetentionPolicy.RUNTIME) //运行期有效
public @interface CacheFind {
String key(); //1.设定key 用户自己设定
int seconds() default 0; //2.可以指定超时时间,也可以不指定.
}
@Component
@Aspect
public class CacheAop {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Around("@annotation(cacheFind)")
public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind){
try {
Object result = null;
//如何动态获取注解中的数据
String prekey = cacheFind.key();
//动态获取方法中的参数 将数组转化为字符串
String args =Arrays.toString(joinPoint.getArgs());
String key = prekey + "::" + args;
if(joinPoint.getArgs()[0].equals(1) && joinPoint.getArgs()[1].equals(10)){//这里指的是当page==0且size==10时候我们走缓存
//检验redis中是否有数据
if(stringRedisTemplate.hasKey(key)){
String json = stringRedisTemplate.opsForValue().get(key);
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Class returnClass = methodSignature.getReturnType();
//将json数据转化为对象
result = ObjectMapperUtil.toObject(json, returnClass);
System.out.println("AOP实现缓存查询!!!!");
}else{
//第一次查询数据库.
result = joinPoint.proceed(); //执行目标方法.
System.out.println("AOP执行数据库操作");
String json = ObjectMapperUtil.toJSON(result);
//2.将数据保存到redis中
if(cacheFind.seconds()>0) //表示需要设定超时时间
stringRedisTemplate.opsForValue().set(key,json,cacheFind.seconds(), TimeUnit.HOURS);
else
//不需要超时
stringRedisTemplate.opsForValue().set(key,json);
}
}else{
result = joinPoint.proceed(); //执行目标方法.
System.out.println("执行数据库操作");
}
return result;
} catch (Throwable throwable) {
throwable.printStackTrace();
throw new RuntimeException(throwable); //将检查异常,转化为运行时异常
}
}
}
简化之后的代码
@Override
@CacheFind(second= 60,key="result")
public ResponseResult listCommentByArticleId(String articleId, int page, int size) {
page = checkPage(page);
size = checkSize(size);
String cacheJson = (String) redisUtils.get(Constants.Comment.KEY_COMMENT_FIRST_PAGE_CACHE + articleId);
Sort sort = new Sort(Sort.Direction.DESC, "state", "createTime");
Pageable pageable = PageRequest.of(page - 1, size, sort);
Page<Comment> all = commentDao.findAllByArticleId(articleId, pageable);
//把结果转成pageList
PageList<Comment> result = new PageList<>();
result.parsePage(all);
return ResponseResult.SUCCESS("评论列表获取成功.").setData(result);
}
你的打赏是我成为首富的动力!