页面缓存的原理:

  普通要想生成一个页面,需要该页面在springboot的templates目录下,然后通过springboot的内部渲染,视图解析器将页面渲染回客户端,这中间会花费很长的时间。

  但如果将整个页面的代码转化为字符串,存到redis中,当请求一个页面时,通过ResponseBody注解,将该字符串直接返回,由客户端自己渲染成页面,那么服务器的压力就会小很多,有效的解决并发。

存在的问题:

  需要合理设置redis缓存的时间,如果设置时间太长,会导致当页面数据本该变化的时候却没有改变,因为缓存的一定是一个静态页面。

实现代码:

@Controller
@RequestMapping("/goods")
public class GoodsController { @Autowired
private MiaoshaUserService miaoshaUserService; @Autowired
private GoodsService goodsService; @Autowired
private RedisService redisService; @Autowired
private ThymeleafViewResolver thymeleafViewResolver; @Autowired
ApplicationContext applicationContext; @RequestMapping(value = "/to_list",produces = "text/html")
@ResponseBody
public String list(Model model, MiaoshaUser user, HttpServletRequest request,HttpServletResponse response){ model.addAttribute("user",user); String html = redisService.get(GoodsKey.getGoodsList, "", String.class);
if(!StringUtils.isEmpty(html)){
System.out.println("从缓存中取");
return html;
} List<GoodsVo> goodsList = goodsService.listGoodsVo(); model.addAttribute("goodsList",goodsList); SpringWebContext ctx = new SpringWebContext(request,response,request.getServletContext(),request.getLocale(),model.asMap(),applicationContext); //手动渲染
html = thymeleafViewResolver.getTemplateEngine().process("goods_list", ctx); if(!StringUtils.isEmpty(html)){
redisService.set(GoodsKey.getGoodsList,"",html);
}
System.out.println("从数据库中取");
return html;
} @RequestMapping(value = "/to_detail/{goodsId}", produces = "text/html")
@ResponseBody
public String detail(HttpServletRequest request,HttpServletResponse response,Model model, MiaoshaUser user,
@PathVariable("goodsId") long goodsId){ model.addAttribute("user",user); String html=redisService.get(GoodsKey.getGoodsDetail,""+goodsId,String.class);
if(!StringUtils.isEmpty(html)){
System.out.println("从缓存中取");
return html;
}
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
model.addAttribute("goods", goods); //得到秒杀的开始时间、结束时间、以及当前时间
long startAt = goods.getStartDate().getTime();
long endAt = goods.getEndDate().getTime();
long now = System.currentTimeMillis(); //设置剩余时间
int remainSeconds=0; //设置秒杀状态
int miaoshaStatus=0; //判断
if(now<startAt){
//秒杀还没开始
miaoshaStatus=0;
remainSeconds= (int) ((startAt-now)/1000);
}else if(now>endAt){
//秒杀已经结束
miaoshaStatus=2;
remainSeconds=-1;
}else {
//秒杀正在进行
miaoshaStatus=1;
remainSeconds=0;
} model.addAttribute("miaoshaStatus",miaoshaStatus);
model.addAttribute("remainSeconds",remainSeconds); SpringWebContext ctx = new SpringWebContext(request,response,request.getServletContext(),request.getLocale(),model.asMap(),applicationContext); //手动渲染
html = thymeleafViewResolver.getTemplateEngine().process("goods_detail", ctx); if(!StringUtils.isEmpty(html)){
redisService.set(GoodsKey.getGoodsDetail,""+goodsId,html);
}
System.out.println("从数据库中取");
return html;
}
}

对象缓存:

对象缓存,如果只是查询某个对象,则比较简单,判断缓存中有没有对象,如果有就返回,如果没有就从数据库中取到,然后放入缓存中,然后返回。

public MiaoshaUser getById(long id){

        MiaoshaUser user = redisService.get(MiaoshaUserKey.getById, ""+id, MiaoshaUser.class);
if(user!=null){
System.out.println("从缓存取");
return user;
}
user = miaoshaUserDao.getById(id);
if(user!=null){
redisService.set(MiaoshaUserKey.getById,""+id,user);
}
System.out.println("从数据库取");
return user;
}

如果涉及到修改对象中的某个值,则需要做的事情比较多,考虑到有并发的存在,因此,我们需要先修改数据库的内容,然后修改缓存的内容。

这里有一篇博客写的很好

比如一个修改密码的方法

public boolean updatePassword(String token, long id, String formPass){
//取出user
MiaoshaUser user = getById(id);
if(user==null){
throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
} user.setPassword(MD5Util.formPassToDBPass(formPass,user.getSalt())); //更新数据库
miaoshaUserDao.update(user); //处理缓存,
redisService.delete(MiaoshaUserKey.getById,""+id);
redisService.set(MiaoshaUserKey.token,token,user); return true;
}
 

最新文章

  1. TypeScript Type Compatibility(类型兼容)
  2. 2014 39th ACM-ICPC 西安赛区 总结
  3. YCSB-压测
  4. git Submodule
  5. js把div固定在页面的右下角
  6. 第一次知道Winform的窗体之间传值怎么写,分享给小白~
  7. cx_Oracle ORA-24315: 非法的属性类型的解决办法
  8. OWIN轻量型框架介绍
  9. Qt 之 入门例程(二)
  10. 安卓巴士android源码、博文精选1
  11. js的join和split
  12. MyBatis进阶(一)运行原理
  13. mysql-8.0 安装教程(自定义配置文件,密码方式已修改)
  14. django restframeowrk filter,search,order
  15. tomcat之性能优化
  16. 00JAVA语法基础_动手动脑
  17. 执行makemigrations后错误集锦
  18. window.open跳过浏览器拦截
  19. BZOJ4992 [Usaco2017 Feb]Why Did the Cow Cross the Road 最短路 SPFA
  20. vs2017配置文件目录

热门文章

  1. LeetCode 89,因为题目晦涩而被点了1500+反对的搜索问题
  2. 041_go语言中的panic
  3. selenium WebDriverWait类等待机制的实现
  4. CSS可见格式化模型
  5. Ant Design Pro入门教程,安装,运行(V5 Typescript版)
  6. JavaScript小游戏实例:简单的键盘练习
  7. 2020-04-07:说出Servlet的生命周期,并说出Servlet和CGI的区别。
  8. golang的树结构三种遍历方式
  9. Linux学习日志——基本指令②
  10. vue 三元表达式当出现elif