Bootstrap

页面缓存、url缓存、对象缓存

页面缓存

页面通用逻辑:

        当用户的请求到达后端时,先去redis中查询缓存,如果缓存中找不到,则进行数据库逻辑操作,然后渲染,存入缓存并返回给前端!如果在缓存中找到了则直接返回给前段。存储在Redis缓存中的页面需要设置时间,根据数据变化是否频繁进行调整,一般都是1、2min。

 

这种缓存一般用于不会经常变动的信息,并且访问次数比较多的页面,这样就不用每次都动态加载了。

商品列表页 页面缓存

当访问list页面时,从缓存中取到就返回这个html,如果取不到,利用ThymeleafViewResolver的getTemplateEngine().process和我们获取到的数据,渲染模板。

并存入缓存,然后返回给前端

一般这个页面缓存,过期时间也不会很长,防止数据的时效性很低(设置为1min,读到的是1min前的页面)。

主要防止短时间内的大并发访问。

@ResponseBody
    @RequestMapping(value = "/to_list",produces = "text/html")
    public String to_list(HttpServletResponse response, HttpServletRequest request,Model model, MiaoshaUser user){//为了方便手机端 移动端,将参数放在请求中
        /*页面缓存*/
        String html = redisService.get(GoodsKey.getGoodsList,"",String.class);
        if (!StringUtils.isEmpty(html)){//从redis 中取, 取得到返回,取不到 手动渲染
            return html;
        }
        model.addAttribute("user",user);
        List<GoodsVo> goodsList = goodsService.getGoodsList();
        model.addAttribute("goodsList",goodsList);
//        return "goods_list";
        /*手动渲染 利用Thymeleaf 的 ThymeleafViewResolver*/
        SpringWebContext ctx = new SpringWebContext(request,response,request.getServletContext(),request.getLocale(),
                model.asMap(), applicationContext); // model 就是将参数存入 ,其中的所有参数 都是为了将页面渲染出来 放入其中,在返回一个静态的html源码
        /*利用 getTemplateEngine()方法的process() 方法,需要传入模板名称和context 变量*/
        html = thymeleafViewResolver.getTemplateEngine().process("goods_list",ctx);//ctx + 模板 返回源码
        /*得到手动渲染的模板*/
        if (!StringUtils.isEmpty(html)){    //不是空,存入缓存
            redisService.set(GoodsKey.getGoodsList,"",html);
        }
        return html;
    }

 

 

对象缓存

相比于页面缓存是更细粒度的缓存 + 缓存更新。

对象缓存就是当用到用户数据的时候,可以从缓存中取出。如:更新用户密码

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

 

/**更新用户密码方法: 涉及到对象缓存 ---若更新对象缓存的相关的数据 要处理缓存
 *  同步数据库和缓存的信息,不然会造成数据不一致的情况
 * */
public boolean updatePassword(String token,long id,String formPassword){
    /*根据id 取出对应用户,更新对应数据*/
    MiaoshaUser user = getById(id);
    if (user == null){//如果没有该用户,说明 手机号不存在
        throw  new GlobalException(CodeMsg.LOGIN_ERROR_USER_NOT_ERROR);
    }
    // 更新数据库 信息
    MiaoshaUser updateUser = new MiaoshaUser();
    updateUser.setId(id);
    /*设置密码 到数据库 ,这时候 应该是formPassword ,更新密码一定是先在前端填入 密码,然后前端做 一次 加密传进来*/
    updateUser.setPassword(Md5Util.formPassToDBPass(formPassword,user.getSalt()));
    miaoshaUserDao.updatePassword(updateUser);
    // 更新完数据库信息,防止缓存中信息不一致,处理缓存 且涉及到所有该对象的缓存都需要处理
    // 一个 是 根据 token 获取对象,所以需要更新 token key 的缓存对象数据, 一个是根据id 获取对象,同理
    /** 处理缓存:
     *  1. 删除相关缓存数据
     *  2. 更新相关缓存中的数据
     * */
    redisService.delete(MiaoshaUserKey.getByName,""+id);//该对象缓存可以直接删,因为没有可以从数据取
    //但是token 缓存不能删除,而是应该修改重新设置,不然就无法登陆了(因为我们登陆是从缓存中取)
    user.setPassword(updateUser.getPassword());
    //将对象 携带新的密码放入缓存
    redisService.set(MiaoshaUserKey.token,token,user);
    return true;
}

原文:https://blog.csdn.net/weixin_38035852/article/details/81054397 

 

;