RedisTemplate(三)spring-redis下的其他接口

一、RedisCallback回调

1、使用场景

org.springframework.data.redis.core.RedisCallback

springboot整合redis后, 我们经常使用RedisTemplate 和StringRedisTemplate两个模板类,

但有时候这并不能满足我们的需求, 需要使用 connect 处理, 除了 redisTemplate.getConnection() 之外, 还可以使用callback机制进行处理。

RedisCallback 是一个回调接口,用于在 Redis 连接上执行单个 Redis 命令,并返回执行命令后的结果。使用 RedisCallback 时,需要手动获取 Redis 连接并释放连接资源。RedisTemplate 类提供了一个 execute 方法,用于执行 Redis 命令并返回执行命令后的结果。

2、使用
@Resource(name = "shardedJedisPool")  
    private ShardedJedisPool shardedJedisPool;  
      
    @Override  
    public <T> T execute(ConnectionCallback<T> action) {  
        ShardedJedis shardedJedis = null;  
        try{  
            // 从连接池中获取jedis分片对象  
            shardedJedis = shardedJedisPool.getResource();  
              
            return action.doInRedis(shardedJedis);  
              
        }catch (Exception e){  
            System.out.println(e.getMessage());  
        }finally {  
            if(null != shardedJedis){  
                shardedJedis.close();  
            }  
        }  
        return null;  
    }  
      
   /** 
     * attention:真正封装的方法,非常的简洁干脆 
     */  
    public String set(final String key, final String value){  
        return execute(new ConnectionCallback<String>() {  
            @Override  
            public String doInRedis(  
                    ShardedJedis shardedJedis) {  
                return shardedJedis.set(key, value);  
            }  
        });  
    }  
      
    public String get(final String key){  
        return execute(new ConnectionCallback<String>(){  
            @Override  
            public String doInRedis(ShardedJedis shardedJedis) {  
                return shardedJedis.get(key);  
            }  
        });  
    }

保存:

redisTemplate.execute(new RedisCallback<Object>() {  
        @Override  
        public Object doInRedis(RedisConnection connection)  
                throws DataAccessException {  
            connection.set(  
                    redisTemplate.getStringSerializer().serialize(  
                            "user.uid." + user.getUid()),  
                    redisTemplate.getStringSerializer().serialize(  
                            user.getAddress()));  
            return null;  
        }  
    });

(2)获取

return redisTemplate.execute(new RedisCallback<User>() {  
        @Override  
        public User doInRedis(RedisConnection connection)  
                throws DataAccessException {  
            byte[] key = redisTemplate.getStringSerializer().serialize(  
                    "user.uid." + uid);  
            if (connection.exists(key)) {  
                byte[] value = connection.get(key);  
                String address = redisTemplate.getStringSerializer()  
                        .deserialize(value);  
                User user = new User();  
                user.setAddress(address);  
                user.setUid(uid);  
                return user;  
            }  
            return null;  
        }  
    });

(3)删除

redisTemplate.execute(new RedisCallback<Object>() {  
        public Object doInRedis(RedisConnection connection) {  
            connection.del(redisTemplate.getStringSerializer().serialize(  
                    "user.uid." + uid));  
            return null;  
        }  
    });

二、SessionCallback

SessionCallback 也是一个回调接口,但是它用于在 Spring Redis 的事务上下文中执行多个 Redis 命令。Spring Redis 的事务管理器会为每个事务提供一个独立的 Redis 连接,以保证事务原子性。在使用 SessionCallback 时,可以通过 RedisOperations 接口来执行多个 Redis 命令,这些命令将在同一事务中被执行。

对比维度RedisCallbackSessionCallback
执行方式逐个执行 Redis 命令将多个 Redis 命令封装在事务内,一次性提交
上下文环境使用 RedisTemplate 时需要手动管理 Redis 连接池Spring 容器自动管理 Redis 连接池
Redis 连接管理手动获取和释放连接Spring 自动管理连接
返回结果根据具体 Redis 命令返回不同类型的结果返回最后一个 Redis 命令的执行结果
执行效率较慢,需要频繁的连接获取和释放快,将多个 Redis 命令封装在一个事务内,减少连接数
使用场景需要手动管理 Redis 连接或者执行单个 Redis 命令时需要原子性操作,保证多个 Redis 命令的一致性时

三、DefaultedRedisConnection

比如在Spring Cache提到了需要自定义清除cache key,重写evict方法

@Override
public void evict(Object key) {
        log.info("key为:{}",key.toString());
        if(key instanceof List<?>) {
            List<String> keys = (List<String>) key;
            //①直接循环调用evict
            //keys.forEach( item -> super.evict(item));
            //②通过connection批量删除key
            byte[][] keysByte = serializeCacheKeys(keys);
            this.redisTemplate = getStringRedisTemplate();
            this.redisTemplate.execute(
                    (RedisCallback<Long>)
                            (connection) -> {
                                return connection.del(keysByte);
                            });
        }else{
            super.evict(key);
        }
 
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w_t_y_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值