java初探(1)之缓存技术

页面缓存的原理:

  普通要想生成一个页面,需要该页面在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;
    }

原文地址:https://www.cnblogs.com/lovejune/p/12342672.html

时间: 2024-10-24 02:05:01

java初探(1)之缓存技术的相关文章

AWT的双缓存技术

学了AWT,学到双缓存技术,于是照着书将双缓存技术的代码给实现了. 另外插一句,swing组件的JComponent组件默认缓存区,不必自己写代码.如果想关闭双缓冲区,可以在组件上施加setDoubleBuffered(false) import java.awt.*; import java.awt.event.*; /* * 双缓存技术 * 可以将绘制的内容保留在一个Image对象中,如果需要重新显示绘制的内容,仅仅简单地将这个Image内容再现就可以了. * (1)img起到缓存的作用,o

(转)java缓存技术,记录

http://blog.csdn.net/madun/article/details/8569860 最近再ITEYE上看到关于讨论JAVA缓存技术的帖子比较多,自己不懂,所以上网大概搜了下,找到一篇,暂作保存,后面如果有用到可以参考.此为转贴,帖子来处:http://cogipard.info/articles/cache-static-files-with-jnotify-and-ehcache 介绍 JNotify:http://jnotify.sourceforge.net/,通过JNI

JAVA缓存技术

最近再ITEYE上看到关于讨论JAVA缓存技术的帖子比较多,自己不懂,所以上网大概搜了下,找到一篇,暂作保存,后面如果有用到可以参考.此为转贴,帖子来处:http://cogipard.info/articles/cache-static-files-with-jnotify-and-ehcache 介绍 JNotify:http://jnotify.sourceforge.net/,通过JNI技术,让Java代码可以实时的监控制定文件夹内文件的变动信息,支持Linux/Windows/MacO

java中的缓存技术该如何实现

1缓存为什么要存在?2缓存可以存在于什么地方?3缓存有哪些属性?4缓存介质? 搞清楚这4个问题,那么我们就可以随意的通过应用的场景来判断使用何种缓存了. 1. 缓存为什么要存在?一 般情况下,一个网站,或者一个应用,它的一般形式是,浏览器请求应用服务器,应用服务器做一堆计算后再请求数据库,数据库收到请求后再作一堆计算后把数据 返回给应用服务器,应用服务器再作一堆计算后把数据返回给浏览器.这个是一个标准流程.但是随着互连网的普及,上网的人越来越多,网上的信息量也越来越 多,在这两个越来越多的情况下

java缓存技术的介绍(转载)

一.什么是缓存1.Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问2.凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之为 Cache 二.缓存的分类1.基于web应用的系统架构图 2.在系统架构的不同层级之间,为了加快访问速度,都可以存在缓存 操作系统磁盘缓存->减少磁盘机械操作 数据库缓存->减少文件系统I/O 应用程序缓存->减少对数据库的查询 Web服务器缓存->减少应用服务器请求 客户端浏览器

java初探(1)之静态页面化——客户端缓存

利用服务端缓存技术,将页面和对象缓存在redis中,可以减少时间浪费,内存开销.但在每次请求的过程中,仍然会有大量静态资源的请求和返回. 使用静态页面技术,页面不必要使用页面交互技术,比如thymeleaf,jsp等.而是写一个纯的html静态页面,然后在页面端通过js的ajax请求,获得数据,并通过配置,将静态页面直接缓存到客户端,等下次请求的时候,如果页面没有发生变化,则可以不用对静态资源进行提交和返回. 当进入商品列表页面时,详情的点击不在通过controller类来将缓存的html返回,

图片内容缓存技术。

在Android加载网络图片一章中当滚动屏幕时会不但调用异步任务重新加载图片,这样即浪费网络资源用户体验也不好,那么我们可以将图片缓存起来,要显示时先从缓存获取.图片缓存的实现分为两种一种内存缓存,一种文件缓存. 内存缓存Google已经帮我们实现,通过LruCache你可以非常方便快速的实现内存缓存. 先简单了解下LruCache原理,Lru是最近最少使用的意思,要做内存缓存首先需要定义缓存空间大小,当缓存空间不够时,系统回收部份内存空间,回收依据是什么呢,这里采用的便是Lru算法,将最近最少

分布式缓存技术redis学习系列(三)——redis高级应用(主从、事务与锁、持久化)

上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性. 回到顶部 安全性设置 设置客户端操作秘密 redis安装好后,默认情况下登陆客户端和使用命令操作时不需要密码的.某些情况下,为了安全起见,我们可以设置在客户端连接后进行任何操作之前都要进行密码验证.修改redis.conf进行配置. [[email protected] ~]# vi /usr/local/redis/etc/redis.conf ###

如何正确使用缓存技术

缓存技术是用来提升程序运行性能的常见手段,如你所见, 阿里巴巴.新浪微博.美团网等互联网龙头企业都是用缓存技术来提升自己家网站的性能.然而,任何事物都有两面性, 缓存技术使用得当带来的好处自然不言而喻, 但是如果使用不当, 产生的副作用也够让人喝一壶的. 我们写服务器程序时,使用缓存的目的无非就是减少数据库访问次数降低数据库的压力和提升程序的响应时间, 然而根据具体的使用场景又可以派生出无数种情况, 比如说 程序频繁读取数据库, 但是查询获得的结果却总是相同的,这部分相同的结果是不是可以放入缓存

硬盘缓存技术DiskLruCache技术&lt;笔记&gt;

防止多图OOM的核心解决思路就是使用LruCache技术,但LruCache只是管理了内存中图片的存储与释放,如果图片从内存中被移除的话,那么又需要从网络上重新加载一次,这显然非常耗时.因此Google又提供了一套硬盘缓存的解决方案:DiskLruCache(非Google官方编写,但获得官方认证).一般来说新闻类App从网络获取到数据后都会存入到本地缓存中,因此即使手机在没有网络的情况下依然能够加载出以前浏览过的新闻.使用的缓存技术自然是DiskLruCache.以网易新闻为例,它的Andro