Redis总结二 - 测试案例

本文详细介绍了如何在Spring Boot项目中配置并使用Redis,包括Redis的连接池配置、序列化方式设置、以及一系列基本操作如设置、获取、删除等。此外,还展示了RedisTemplate的使用,以及Redis在实际场景中的应用,如哈希、列表、集合、有序集合、位运算等。通过实例演示了RedisUtils工具类的实现和RedisController中关键API的调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

搭建springboot项目

application.yml

server:
  port: 9001
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    jedis:
      pool:
        max-wait: 30000 #连接池最大阻塞等待时间,使用负值表示没有限制
        max-active: 100 #连接池最大连接数,使用负值表示没有限制
        max-idle: 20 #连接池中的最大空闲连接
        min-idle: 0 #连接池中的最小空闲连接
        timeout: 3000 #连接超时

pom.xml

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-redis</artifactId>
			<version>1.4.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.3</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
		</dependency>
        <dependency>
            <groupId>com.touch</groupId>
            <artifactId>springtest</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-log4j2</artifactId>
		</dependency>
    </dependencies>

RedisConfig.java

@Configuration
public class RedisConfig extends CachingConfigurerSupport{

    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

RedisUtils.java

@Component
public class RedisUtils {

    @Autowired
    private RedisTemplate redisTemplate;

    public RedisUtils(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 写入缓存
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 写入缓存设置时效时间
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime ,TimeUnit timeUnit) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, timeUnit);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 批量删除对应的value
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }
    /**
     * 批量删除key
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0){
            redisTemplate.delete(keys);
        }
    }
    /**
     * 删除对应的value
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }
    /**
     * 判断缓存中是否有对应的value
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }
    /**
     * 读取缓存
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }
    /**
     * 哈希 添加
     * @param key
     * @param hashKey
     * @param value
     */
    public void hmSet(String key, Object hashKey, Object value){
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key,hashKey,value);
    }
    /**
     * 哈希获取数据
     * @param key
     * @param hashKey
     * @return
     */
    public Object hmGet(String key, Object hashKey){
        HashOperations<String, Object, Object>  hash = redisTemplate.opsForHash();
        return hash.get(key,hashKey);
    }
    /**
     * 列表添加
     * @param k
     * @param v
     */
    public void lPush(String k,Object v){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k,v);
    }
    /**
     * 列表获取
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> lRange(String k, long l, long l1){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k,l,l1);
    }
    /**
     * 集合添加
     * @param key
     * @param value
     */
    public void add(String key,Object value){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key,value);
    }
    /**
     * 集合获取
     * @param key
     * @return
     */
    public Set<Object> setMembers(String key){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }
    /**
     * 有序集合添加
     * @param key
     * @param value
     * @param scoure
     */
    public void zAdd(String key,Object value,double scoure){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key,value,scoure);
    }
    /**
     * 有序集合获取
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> rangeByScore(String key, double scoure, double scoure1){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }

    /**
     * 设置key字段第offset位bit数值
     *
     * @param key    字段
     * @param offset 位置
     * @param value  数值
     */
    public void setBit(String key, long offset, boolean value) {
        redisTemplate.execute((RedisCallback) con -> con.setBit(key.getBytes(), offset, value));
    }

    /**
     * 判断该key字段offset位否为1
     *
     * @param key    字段
     * @param offset 位置
     * @return 结果
     */
    public boolean getBit(String key, long offset) {
        return (boolean) redisTemplate.execute((RedisCallback) con -> con.getBit(key.getBytes(), offset));
    }

    /**
     * 统计key字段value为1的总数
     *
     * @param key 字段
     * @return 总数
     */
    public Long bitCount(String key) {
        return (Long) redisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
    }

    /**
     * 统计key字段value为1的总数,从start开始到end结束
     *
     * @param key   字段
     * @param start 起始
     * @param end   结束
     * @return 总数
     */
    public Long bitCount(String key, Long start, Long end) {
        return (Long) redisTemplate.execute((RedisCallback) con -> con.bitCount(key.getBytes(), start, end));
    }

    /**
     * 取多个key并集并计算总数
     *
     * @param key key
     * @return 总数
     */
    public Long OpOrCount(String... key) {
        byte[][] keys = new byte[key.length][];
        for (int i = 0; i < key.length; i++) {
            keys[i] = key[i].getBytes();
        }
        redisTemplate.execute((RedisCallback) con -> con.bitOp(RedisStringCommands.BitOperation.OR, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
        redisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
        return bitCount(key[0] + "To" + key[key.length - 1]);
    }

    /**
     * 取多个key的交集并计算总数
     *
     * @param key key
     * @return 总数
     */
    public Long OpAndCount(String... key) {
        byte[][] keys = new byte[key.length][];
        for (int i = 0; i < key.length; i++) {
            keys[i] = key[i].getBytes();
        }
        redisTemplate.execute((RedisCallback) con -> con.bitOp(RedisStringCommands.BitOperation.AND, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
        redisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
        return bitCount(key[0] + "To" + key[key.length - 1]);
    }

    /**
     * 取多个key的补集并计算总数
     *
     * @param key key
     * @return 总数
     */
    public Long OpXorCount(String... key) {
        byte[][] keys = new byte[key.length][];
        for (int i = 0; i < key.length; i++) {
            keys[i] = key[i].getBytes();
        }
        redisTemplate.execute((RedisCallback) con -> con.bitOp(RedisStringCommands.BitOperation.XOR, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
        redisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
        return bitCount(key[0] + "To" + key[key.length - 1]);
    }

    /**
     * 取多个key的否集并计算总数
     *
     * @param key key
     * @return 总数
     */
    public Long OpNotCount(String... key) {
        byte[][] keys = new byte[key.length][];
        for (int i = 0; i < key.length; i++) {
            keys[i] = key[i].getBytes();
        }
        redisTemplate.execute((RedisCallback) con -> con.bitOp(RedisStringCommands.BitOperation.NOT, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
        redisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
        return bitCount(key[0] + "To" + key[key.length - 1]);
    }

    public List<Long> bitField(String buildSignKey,int limit,int offset){
        return (List<Long>)redisTemplate.execute((RedisCallback<List<Long>>) con ->
                con.bitField(buildSignKey.getBytes(),
                        BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(limit)).valueAt(offset)));
    }

    public Long setHyperLogLog(String key,Object...values){
        return redisTemplate.opsForHyperLogLog().add(key,values);
    }

    public Long getHyperLogLog(Object...keys){
        return redisTemplate.opsForHyperLogLog().size(keys);
    }

    public BoundGeoOperations setGeo(Object key){
        return redisTemplate.boundGeoOps(key);
    }
}

RedisController.java

@RestController
@RequestMapping("/redis")
@Slf4j
public class RedisController {

    @Resource
    private RedisUtils redisUtils;

    @RequestMapping("/set")
    public void redisSet(){
        //String
        redisUtils.set("String","中文");
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        redisUtils.set("list",list);
        redisUtils.set("user2",new User("210123","阿丹",25));
        //hash
        redisUtils.hmSet("user1","userhash",new User("210123","阿丹",25));
        User user = (User)redisUtils.hmGet("user1","userhash");
        log.info("hash-object:{}",user);
        //列表添加
        redisUtils.lPush("list1","a");
        redisUtils.lPush("list1","b");
        List<Object> listValue = redisUtils.lRange("list1",0,list.size());
        log.info("listValue-object:{}",listValue);
        //集合添加
        Map<String,User> map = new HashMap<>();
        map.put("adan",new User("210123","阿丹",25));
        map.put("adana",new User("210123","阿丹a",18));
        redisUtils.add("collection",map);
        Set<Object> set = redisUtils.setMembers("collection");
        log.info("setValue-object:{}",set);
        //有序集合
        redisUtils.zAdd("collection-order","18",1);
        redisUtils.zAdd("collection-order","12",2);
        redisUtils.zAdd("collection-order","14",4);
        redisUtils.zAdd("collection-order","123",3);
        Set<Object> zset = redisUtils.rangeByScore("collection-order",1,5);
        log.info("zsetValue-object:{}",zset);
        //bitmap
        redisUtils.setBit("bitmap",1,true);
        redisUtils.setBit("bitmap",0,true);
        boolean bit = redisUtils.getBit("bitmap",1);
        log.info("bitmapValue-boolean:{}",bit);
        long count = redisUtils.bitCount("bitmap");
        log.info("bitmapValue-count:{}",count);
        long start = 0;
        long end = 7;
        long count2 = redisUtils.bitCount("bitmap",start,end);
        log.info("bitmapValue-count2:{}",count2);
        List<Long> bitFiledLong = redisUtils.bitField("bitmap",2,0);
        log.info("bitmapValue-bitFiledLong:{}",bitFiledLong);
        // 在线用户
        String onlineKey = "online:";
        for (int i = 0; i < 100; i++) {
            redisUtils.setBit(onlineKey, i, i % 2 == 0);
        }
        for (int i = 0; i < 10; i++) {
            log.info("{}={}" ,i, redisUtils.getBit(onlineKey, i));
        }
        log.info("online:{}",redisUtils.bitCount(onlineKey));
        // IP去重复统计
        final String logLogKey = "loglog:";
        String[] arr = new String[100];
        for (int i = 0; i < 100;i++) {
            arr[i] = "A" + new Random().nextInt(10) + 1;
        }
        redisUtils.setHyperLogLog(logLogKey, arr);
        log.info("arr:{}",arr);
        log.info("logLog:{}",redisUtils.getHyperLogLog(logLogKey));

        BoundGeoOperations boundGeoOperations = redisUtils.setGeo("CHINA:CITY");
        Point nanjing = new Point(118.803805, 32.060168);
        boundGeoOperations.add(nanjing, "南京市");
        Point beijing = new Point(116.397039, 39.9077);
        boundGeoOperations.add(beijing, "北京市");
        Point shanghai = new Point(120.52, 30.40);
        boundGeoOperations.add(shanghai, "上海市");
        //geodist:获取两个地理位置的距离
        Distance distance = boundGeoOperations.distance("南京市","北京市", Metrics.KILOMETERS);
        log.info("南京市到北京市之间的距离是:{}km" ,distance.getValue());
        Distance distance2 = boundGeoOperations.distance("南京市", "上海市", Metrics.KILOMETERS);
        log.info("南京市到上海市之间的距离是:{}km", distance2.getValue());
        //geohash:获取某个地理位置的geohash值
        List<String> list2 = boundGeoOperations.hash("南京市");
        log.info("南京市的geoHash = {}", list2.get(0));
        //geopos:获取某个地理位置的坐标
        List<Point> pointList = boundGeoOperations.position("南京市");
        log.info("南京市的经纬度为 = {} ", pointList.get(0));
        //georadius:根据给定地理位置坐标获取指定范围内的地理位置集合
        // 查询南京市1000KM范围内的城市
        Circle within = new Circle(nanjing, 1000000);
        //设置geo查询参数
        RedisGeoCommands.GeoRadiusCommandArgs geoRadiusArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        //查询返回结果包括距离和坐标
        geoRadiusArgs = geoRadiusArgs.includeCoordinates().includeDistance();
        //按查询出的坐标距离中心坐标的距离进行排序
        geoRadiusArgs.sortAscending();
        //限制查询返回的数量
        geoRadiusArgs.limit(2);
        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = boundGeoOperations.radius(within, geoRadiusArgs);
        List<GeoResult<RedisGeoCommands.GeoLocation<String>>> geoResultList = geoResults.getContent();
        for (GeoResult geoResult : geoResultList) {
            log.info("geoRadius {} " , geoResult.getContent());
        }
        //georadiusbymember:根据给定地理位置获取指定范围内的地理位置集合
        geoRadiusArgs.limit(1); geoResults = boundGeoOperations.radius("南京市", new Distance(1000000), geoRadiusArgs);
        geoResultList = geoResults.getContent();
        for (GeoResult geoResult : geoResultList) {
            log.info("geoRadiusByMember {}" , geoResult.getContent());
        } //删除位置信息,此命令不是geo提供的,是使用zrem命令删除的
        boundGeoOperations.remove("南京市");
    }
}

log

hash-object:User(account=210123, name=阿丹, age=25)
listValue-object:[a, b, a, b]
setValue-object:[{adana=User(account=210123, name=阿丹a, age=18), adan=User(account=210123, name=阿丹, age=25)}]
zsetValue-object:[18, 12, 123, 14]
bitmapValue-boolean:true
bitmapValue-count:2
bitmapValue-count2:2
bitmapValue-bitFiledLong:[3]
0=true
1=false
...

online:50
arr:A61
logLog:10
南京市到北京市之间的距离是:899.2222km
南京市到上海市之间的距离是:246.4453km
南京市的geoHash = wtsqrkqk120
南京市的经纬度为 = Point [x=118.803805, y=32.060168] 
geoRadius RedisGeoCommands.GeoLocation(name=南京市, point=Point [x=118.803805, y=32.060168]) 
geoRadius RedisGeoCommands.GeoLocation(name=上海市, point=Point [x=120.520001, y=30.400000]) 
geoRadiusByMember RedisGeoCommands.GeoLocation(name=南京市, point=Point [x=118.803805, y=32.060168])

图1
图2
图3
图4

图5
图6
图7
图8
图9
图10
图11
图12

虽然总结了,但是理解还不是很透彻!!!
菜了菜了!!!

参考:
https://www.sohu.com/a/300039010_114877
https://www.matools.com/blog/190329767
https://blog.csdn.net/weixin_39765695/article/details/110726589
https://www.jianshu.com/p/5596c3a4978d

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值