1. 程式人生 > 其它 >redisTemplate類學習及理解

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方法,可以具體檢視。