redisTemplate类学习及理解


List<Object> list = masterRedisTemplate.executePipelined((RedisCallback<Long>) connection -> {
            StringRedisConnection redisConn = (StringRedisConnection) connection;
            Integer expireTime = XXX;
            redisConn.expire(XXX);
            RedisUtil.addSameScoreTail(XXXX);
            return null;
        });

 

 

    redisTemplate简化Redis数据访问代码的Helper类。在给定对象和中的基础二进制数据之间执行自动序列化/反序列化。中心方法是execute,支持实现X接口的Redis访问代码,它提供了RedisConnection处理,使得RedisCallback实现和调用代码都不需要显式关心检索/关闭Redis连接,或处理连接生命周期异常。对于典型的单步动作,有各种方便的方法。一旦配置好,这个类就是线程安全的。这是Redis支持的核心类。

  1 public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
      
接口 RedisAccessor:,该接口指定了一组基本的Redis操作,由RedisTemplate实现。不经常使用,但对于可扩展性和可测试性来说是一个有用的选项(因为它很容易被模仿或存根)。
     

2
private boolean enableTransactionSupport = false;
      true:开启之后则开启事务;
  3     private boolean exposeConnection = false;
      
曝光链接

    @Override
    public List<Object> executePipelined(RedisCallback<?> action, @Nullable RedisSerializer<?> resultSerializer) {

      return execute((RedisCallback<List<Object>>) connection -> {

首先开通连接
        connection.openPipeline();

标志连接是否关闭  这里有个问题时下面这个true设置是为什么 后续是不是会改为false,要不导致内存泄漏了。 :::在deserialize这个方法里传的closePipline参数可以把关闭连接传递过去。
        boolean pipelinedClosed = false;
        try {

其次处理传来的action的doInRedis方法。 这个doinredis方法就是本文第一个代码块的代码,即当前方法入参传过来的代码块的内容。
Object result = action.doInRedis(connection);
          if (result != null) {
            throw new InvalidDataAccessApiUsageException(
              "Callback cannot return a non-null value as it gets overwritten by the pipeline");
            }
            List<Object> closePipeline = connection.closePipeline();
            pipelinedClosed = true;

最后调用deserializeMixedResults,把返回结果带入到execute去继续执行。  这个是一个反序列化相关的方法。
return deserializeMixedResults(closePipeline, resultSerializer, hashKeySerializer, hashValueSerializer);
        } finally {
          if (!pipelinedClosed) {
  connection.closePipeline();
        }
        }
      });
    }

StringRedisConnection redisConn = (StringRedisConnection) connection; 在调用executePipelined前,可以用来操作数据。

  这个execute是executePipelined处理的具体实现。

   @Nullable
public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) { Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it"); Assert.notNull(action, "Callback object must not be null"); RedisConnectionFactory factory = getRequiredConnectionFactory(); RedisConnection conn = null; try { if (enableTransactionSupport) { // only bind resources in case of potential transaction synchronization conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport); } else { conn = RedisConnectionUtils.getConnection(factory); } boolean existingConnection = TransactionSynchronizationManager.hasResource(factory); RedisConnection connToUse = preProcessConnection(conn, existingConnection); boolean pipelineStatus = connToUse.isPipelined(); if (pipeline && !pipelineStatus) { connToUse.openPipeline(); } RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse)); T result = action.doInRedis(connToExpose);
具体执行的也是本文最上面的代码块里的方法。
// close pipeline if (pipeline && !pipelineStatus) { connToUse.closePipeline(); } // TODO: any other connection processing? return postProcessResult(result, connToUse, existingConnection); } finally { RedisConnectionUtils.releaseConnection(conn, factory); } }

 


 

redisTemplate其他方法

delete

@Override
    public Boolean delete(K key) {
      key转成序列化的
        byte[] rawKey = rawKey(key);
      调用execute方法
        Long result = execute(connection -> connection.del(rawKey), true);
      判断返回值
        return result != null && result.intValue() == 1;
    }

这个execute也是调用的上面的execute方法,获取到连接之后,执行代码块里的del命令。

 

expire

加失效时间

@Override
    public Boolean expire(K key, final long timeout, final TimeUnit unit) {
      序列化
        byte[] rawKey = rawKey(key);
      计算超时时间
long rawTimeout = TimeoutUtils.toMillis(timeout, unit); return execute(connection -> { try {
          调用
return connection.pExpire(rawKey, rawTimeout); } catch (Exception e) { // Driver may not support pExpire or we may be running on Redis 2.4 return connection.expire(rawKey, TimeoutUtils.toSeconds(timeout, unit)); } }, true); }

 

计算好了之后 同样也是通过execute方法,获取连接后执行。

 

 

opsForHash

RedisTemplate.opsForHash().put/get/delete等等
HashOperations

 

 @Override
    public <HK, HV> HashOperations<K, HK, HV> opsForHash() {
        return new DefaultHashOperations<>(this);
    }

这个方法实现了hashOperations接口
class DefaultHashOperations<K, HK, HV> extends AbstractOperations<K, Object> implements HashOperations<K, HK, HV> {

    @SuppressWarnings("unchecked")
    DefaultHashOperations(RedisTemplate<K, ?> template) {
        super((RedisTemplate<K, Object>) template);
    }
}

 

@Override
    public void put(K key, HK hashKey, HV value) {

        byte[] rawKey = rawKey(key);
        byte[] rawHashKey = rawHashKey(hashKey);
        byte[] rawHashValue = rawHashValue(value);

        execute(connection -> {
这里通过execute方法,把这个代码块执行。具体的参数是key ,hashkey,value 的三个序列化之后的参数。 connection.hSet(rawKey, rawHashKey, rawHashValue);
return null; }, true); }

 

 

OpsForSet()

RedisTemplate.opsForSet().add(key, value);


public Long add(K key, V... values) {
      序列化
        byte[] rawKey = rawKey(key);
      values是多组二进制
byte[][] rawValues = rawValues((Object[]) values);
      
return execute(connection -> connection.sAdd(rawKey, rawValues), true); }

 

大致就是相关的用法,不通的数据结构 ,有自己特有的Operations方法,可以具体查看。

 

posted @ 2022-03-17 15:29  CodingOneTheWay  阅读(459)  评论(0编辑  收藏  举报
回到顶部