Google GauvaCache的使用

DBC 1.3K 0

一、LoadingCache

guava缓存的expireAfterWrite与refreshAfterWrite的区别

  • expireAfterWrite是在指定项在一定时间内没有创建/覆盖时,会移除该key,下次取的时候从loading中取
  • expireAfterAccess是指定项在一定时间内没有读写,会移除该key,下次取的时候从loading中取
  • refreshAfterWrite是在指定时间内没有被创建/覆盖,则指定时间过后,再次访问时,会去刷新该缓存,在新值没有到来之前,始终返回旧值
  • 跟expire的区别是,指定时间过后,expire是remove该key,下次访问是同步去获取返回新值
  • 而refresh则是指定时间后,不会remove该key,下次访问会触发刷新,新值没有回来时返回旧值

加依赖

   <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
   <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>28.0-jre</version>
   </dependency>

简单使用

    LoadingCache<Integer,List<TCoupon>> couponCache = CacheBuilder.newBuilder()
            .expireAfterWrite(10,TimeUnit.MINUTES).refreshAfterWrite(5,TimeUnit.MINUTES)
            .build(new CacheLoader<Integer, List<TCoupon>>() {
                @Override
                public List<TCoupon> load(Integer o) throws Exception {
                    return loadCoupon(o);
                }
            });

    private List<TCoupon> loadCoupon(Integer o) {
        TCouponExample example = new TCouponExample();
        example.createCriteria().andStatusEqualTo(Constant.USERFUL)
                .andStartTimeLessThan(new Date()).andEndTimeGreaterThan(new Date());
        return tCouponMapper.selectByExample(example);
    }

    public void print(){
        System.err.println("enter coupon service");
    }

    /***
     * 获取有效时间的可用优惠券列表
     * @return
     */
    public List<TCoupon> getCouponList(){
        List<TCoupon> tCoupons = Lists.newArrayList();
        try {
            tCoupons =  couponCache.get(1);
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return tCoupons;
        // 1、是否存在远程调用 HTTP、RPC Metrics
        // 2、大量内存处理  list.contain() ==>set.contain
    }

Google GauvaCache的使用插图

温馨提示

博主点到手都烂了,依然还是一条sql![aru_42]

二、Google GuavaCache实战批量优惠券ID接口

问题抛出
  • 有这样一种情况,我们需要通过id批量查询优惠券,如以下的数据,如果我们用这个字符串来作为缓存,那么这三条请求过来,我们会查三次数据库,尽管请求的东西越来越少而且还有重复,那么我们应该怎么解决呢?
    • “1,2,3,4,5”,“1,2,3”,“1”
  • 解决方案:
    • 我们通过每一个id来作为key进行存储,这样一来经过第一个请求,我们就缓存了5条优惠券,后面来的数据我们都可以走缓存了,这样就大大计加快了我们查找的速度!

简单的小例子

 LoadingCache<Integer,TCoupon> couponIdsCache = CacheBuilder.newBuilder()
            .expireAfterWrite(10,TimeUnit.MINUTES).refreshAfterWrite(5,TimeUnit.MINUTES)
            .build(new CacheLoader<Integer,TCoupon>() {
                @Override
                public TCoupon load(Integer o) throws Exception {
                    return loadIdCoupon(o);
                }
            });

    private TCoupon loadIdCoupon(Integer id) {
        return tCouponMapper.selectByPrimaryKey(id);
    }
    public List<TCoupon> getCouponListByIds(String ids){
        String[] idStr = ids.split(",");
        List<Integer> loadFromDB = Lists.newArrayList();
        List<TCoupon> tCoupons = Lists.newArrayList();
        List<String> idList = Lists.newArrayList(idStr);
        for (String id:idList) {
            //拿值,如果拿到返回,如果拿不到就是null
            TCoupon tCoupon =  couponIdsCache.getIfPresent(id);
            if (tCoupon==null){
                loadFromDB.add(Integer.parseInt(id));
            }else {
                tCoupons.add(tCoupon);
            }
        }
        List<TCoupon> tCoupons1 = couponByIds(loadFromDB);
        Map<Integer,TCoupon> tCouponMap = tCoupons1.stream().collect(Collectors.toMap(TCoupon::getId, TCoupon->TCoupon));
        tCoupons.addAll(tCoupons1);
        //将返回结果回写到缓存里面
        couponIdsCache.putAll(tCouponMap);
        return tCoupons;
    }



    private List<TCoupon> couponByIds(List<Integer> ids) {
        TCouponExample example = new TCouponExample();
        example.createCriteria().andIdIn(ids);
        return tCouponMapper.selectByExample(example);
    }
温馨提示

相信代码看起来也很清晰,实现的逻辑博主已经说明得很详细了!

发表评论 取消回复
表情 图片 链接 代码

分享