redis黑马实战部分002

11 GEO数据结构的基本用法

添加坐标,底层使用zset实现

GEOADD g1 116.378248 39.865275 bjn 116.42803 39.903738 bjz 116.322287 39.893729 bjx

两个点之间距离

geodist g1 bjn bjx km

某坐标附近10km内所有火车站以及距离。

GEOSEARCH g1 fromlonlat 116.397904 39.909005 byradius 10 km withdist

12 导入数据到GEO

导入代码

	@Test
    void loadShopData() {
        // 1.查询店铺信息
        List<Shop> list = shopService.list();
        // 2.把店铺分组,按照typeId分组,typeId一致的放到一个集合
        Map<Long, List<Shop>> map = list.stream().collect(Collectors.groupingBy(Shop::getTypeId));
        // 3.分批完成写入Redis
        for (Map.Entry<Long, List<Shop>> entry : map.entrySet()) {
            // 3.1.获取类型id
            Long typeId = entry.getKey();
            String key = SHOP_GEO_KEY + typeId;
            // 3.2.获取同类型的店铺的集合
            List<Shop> value = entry.getValue();
            List<RedisGeoCommands.GeoLocation<String>> locations = new ArrayList<>(value.size());
            // 3.3.写入redis GEOADD key 经度 纬度 member
            for (Shop shop : value) {
                // stringRedisTemplate.opsForGeo().add(key, new Point(shop.getX(), shop.getY()), shop.getId().toString());
                locations.add(new RedisGeoCommands.GeoLocation<>(
                        shop.getId().toString(),
                        new Point(shop.getX(), shop.getY())
                ));
            }
            stringRedisTemplate.opsForGeo().add(key, locations);
        }
    }

结果

在这里插入图片描述

15 BitMap功能演示

背景

用户数量很大,数据量非常大。
程序实现签到卡功能。
把每一个bit对应当月的每一天,形成映射关系。位图。

BITFIELD  查询数组中指定位置的值,一次可以查询多个。

BITOPS  查找bit数组指定范围内第一个出现0或1的位置。

应用

获取多个比特位的结果

bitfield bm1 get u2 0

查找第一个元素出现的位置

 bitpos bm1 1

16 实现签到功能

将当前用户当天签到信息保存到redis中。

代码

	public Result sign() {
        // 1.获取当前登录用户
        Long userId = UserHolder.getUser().getId();
        // 2.获取日期
        LocalDateTime now = LocalDateTime.now();
        // 3.拼接key
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key = USER_SIGN_KEY + userId + keySuffix;
        // 4.获取今天是本月的第几天
        int dayOfMonth = now.getDayOfMonth();
        // 5.写入Redis SETBIT key offset 1
        stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);
        return Result.ok();
    }

测试及结果

在这里插入图片描述

其中使用工具后台插入一条数据

在这里插入图片描述

17 统计连续签到

获取本月截至今天为止的所有签到数据。

与1做与运算,得到这个数本身。

代码

	public Result signCount1() {

        //获取当前登录用户
        Long userId = UserHolder.getUser().getId();

        //获取当前日期
        LocalDateTime now = LocalDateTime.now();

        //拼接key
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key=USER_SIGN_KEY+userId+keySuffix;

        //当前是这个月的第几天
        int dayOfMonth = now.getDayOfMonth();

        //获取本月为止的签到记录
        List<Long> result = stringRedisTemplate.opsForValue().bitField(key, BitFieldSubCommands.create()
                .get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));

        if(result==null||result.isEmpty()){
            //没有任何签到结果
            return Result.ok(0);
        }
        Long num = result.get(0);
        if(num==null||num==0){
            return Result.ok(0);
        }

        //循环遍历
        int count=0;
        while (true){

            //6.1 让这个数字和1 与运算 得到结果最后一位bit位
            if((num&1)==0){
                //判断是否为0
                break;
            }else {
                count++;
            }
            num>>>=1;
        }
        return Result.ok(count);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值