springboot整合redis三种特殊数据类型 bitmaps、 hyperloglogs、geospatial介绍、应用场景以及简单使用

添加工具类SpringUtils

@Component
public class SpringUtils implements ApplicationContextAware {
    
    private static ApplicationContext applicationContext;

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringUtils.applicationContext == null) {
            SpringUtils.applicationContext = applicationContext;
        }
    }

    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    public static <T> T getBean(Class<T> c) {
        return getApplicationContext().getBean(c);
    }

    public static <T> T getBean(String name, Class<T> c) {
        return getApplicationContext().getBean(name, c);
    }

}

1、bitmaps

介绍

位图,基于最小的单位bit进行存储,设置时候时间复杂度O(1)、读取时候时间复杂度O(n),占用空间小。bit映射被限制在512MB之内,所以最大是2^32位。

应用场景

生活中有着两种状态的场景,比如用户每日是否登录,用户是否在线、是否有网购记录,员工是否打卡等具有两种状态的场景,我们可以使用bitmaps来进行记录、查询、统计等等功能。

使用

    @Test
    public void testBitMaps(){//位图使用
        //此处必须使用StringRedisTemplate,否则bitcount功能失效
        StringRedisTemplate stringRedisTemplate = SpringUtils.getBean(StringRedisTemplate.class);
        String key = "sign";
        ValueOperations operations = stringRedisTemplate.opsForValue();
        stringRedisTemplate.delete(key);
        System.out.println("key是否存在:"+stringRedisTemplate.hasKey(key));
        operations.setBit(key,0,true);//设置新值返回旧值
        operations.setBit(key,1,true);
        operations.setBit(key,2,false);
        operations.setBit(key,3,true);
        operations.setBit(key,4,true);
        operations.setBit(key,5,false);
        operations.setBit(key,6,false);

        System.out.println(operations.getBit(key,4));//获取key对应的第5个位的值
        System.out.println(operations.getBit(key,6));//获取key对应的第7个位的值
        System.out.println(operations.getBit(key,7));//获取key对应的第8个位的值,如果不存在则返回false

        System.out.println(operations.getBit(key,3));//获取key对应的第4个位的值
        //统计key中value为true的数量
        long count = (long)stringRedisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
        System.out.println(count);
        //统计key中指定范围内value为true的数量
        count = (long)stringRedisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes(),1,5));
        System.out.println(count);

    }

2、hyperloglogs

介绍

HyperLogLog是一个用于统计唯一性事物数量的概率性数据结构(专业的说这叫估算集合的基数)。通常统计总数需要消耗与数量成正比例的存储空间,为了避免重复统计一个项多次你需要把你已经统计过的项记录下来,然而存在一种算法,损耗一定的精确度来节省存储空间,用一种带有一定误差的估算方式,在redis的实现中,这种误差小于1%。这种算法的魔力在于,你不再需要使用和已存储元素的数目成比例的存储空间,取而代之只使用固定数目的内存,在最差的情况下也仅仅需要12Kb的内存!如果你的元素数目很少,消耗的内存会更少。

应用场景

统计注册的IP数,每日访问数,每天在线人数,搜索词条数等类似场景。

使用

    @Test
    public void testHyperLogLog(){
        String key1 = "HyperLogLog1";
        String key2 = "HyperLogLog2";
        String desKey = "desHyperLogLog";
        HyperLogLogOperations operations = redisTemplate.opsForHyperLogLog();
        //给基数添加元素
        operations.add(key1, "a", "b", "c");
        operations.add(key2, "d", "e", "f","g");

        //返回HyperLogLog的基数值
        Long size = operations.size(key1);
        System.out.println(key1+"的基数值: " + size);

        size = operations.size(key2);
        System.out.println(key2+"的基数值: " + size);

        //获取两个基数集合的并集
        size = operations.union(desKey,key1,key2);
        System.out.println(desKey+"的基数值: " + size);
        
    }

3、geospatial

介绍

将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。这些数据将会存储到sorted set这样的目的是为了方便使用GEORADIUS或者GEORADIUSBYMEMBER命令对数据进行半径查询等操作。

应用场景

比如微信位置共享,附近的人等地图功能。

使用

    @Test
    public void testGeoSpatial(){//reids 3.2版本之后支持
        String citys = "citys";
        String chengdu = "chengdu";
        String beijing = "beijing";
        String chongqing = "beijing";
        String luzhou = "beijing";
        GeoOperations<String, String> geoOperations = redisTemplate.opsForGeo();
        geoOperations.add(citys,new RedisGeoCommands.GeoLocation<String>(chengdu,new Point(104,30)));
        geoOperations.add(citys,new Point(116,40),beijing);
        geoOperations.add(citys,new Point(106,29),chongqing);
        geoOperations.add(citys,new Point(105,25),luzhou);

        System.out.println(geoOperations.position(citys, "chengdu"));//获取成都经纬度
        System.out.println(geoOperations.distance(citys, chengdu, beijing));//获取两地距离

        Point center = new Point(104,30);//定义中心点
        Distance radius = new Distance(800, Metrics.KILOMETERS);//定义范围
        Circle within = new Circle(center, radius);
        //返回范围内的城市
        System.out.println(geoOperations.radius(citys, within));
        //根据距离排序,返回最近的两个
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.
                newGeoRadiusArgs().includeDistance().limit(2).sortAscending();
        System.out.println(geoOperations.radius(citys, within, args));

    }

github地址

https://github.com/JsonTom888/database/tree/main/springboot_redis

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值