在spring-data-redis中使用lua腳本

參考

Lua 腳本
Programming in Lua

api

  • 使用 RedisScript<T>
  • 使用 RedisTemplate.execute(RedisScript<T> script, List<K> keys, Object... args)

幾點(diǎn)需要關(guān)注的地方

redisScript.resultType

事實(shí)上, DefaultScriptExecutor 拿到 connection.eval 的返回結(jié)果后, 只是判斷 redisScript.resultType 是否為空,為空則直接返回為空,
如果不為空, 則根據(jù) 返回結(jié)果是 byte[] 還是 list 調(diào)用反序列化函數(shù)進(jìn)行反序列化。

    protected <T> T eval(RedisConnection connection, RedisScript<T> script, ReturnType returnType, int numKeys,
                byte[][] keysAndArgs, RedisSerializer<T> resultSerializer) {
    
            Object result;
            try {
                result = connection.evalSha(script.getSha1(), returnType, numKeys, keysAndArgs);
            } catch (Exception e) {
    
                if (!exceptionContainsNoScriptError(e)) {
                    throw e instanceof RuntimeException ? (RuntimeException) e : new RedisSystemException(e.getMessage(), e);
                }
    
                result = connection.eval(scriptBytes(script), returnType, numKeys, keysAndArgs);
            }
    
            if (script.getResultType() == null) {
                return null;
            }
    
            return deserializeResult(resultSerializer, result);
    }
        
    ....
    
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected <T> T deserializeResult(RedisSerializer<T> resultSerializer, Object result) {
        if (result instanceof byte[]) {
            if (resultSerializer == null) {
                return (T) result;
            }
            return resultSerializer.deserialize((byte[]) result);
        }
        if (result instanceof List) {
            List results = new ArrayList();
            for (Object obj : (List) result) {
                results.add(deserializeResult(resultSerializer, obj));
            }
            return (T) results;
        }
        return (T) result;
    }
    

而序列化工具類則是調(diào)用 RedisTemplate

public <T> T execute(final RedisScript<T> script, final List<K> keys, final Object... args) {
        // use the Template's value serializer for args and result
        return execute(script, template.getValueSerializer(), (RedisSerializer<T>) template.getValueSerializer(), keys,
                args);
}
返回值

redis 的返回值里, 只有 byte[] 字節(jié), 或者 list<byte[]> 的我值數(shù)據(jù), 所以不要寫以下的代碼
foo 下的數(shù)據(jù)不會(huì)返回.

local result = { foo = "name", "breaker", "time" }
return result

關(guān)于參數(shù)


    @SuppressWarnings("unchecked")
    public <T> T execute(final RedisScript<T> script, final List<K> keys, final Object... args) {
        // use the Template's value serializer for args and result
        return execute(script, template.getValueSerializer(), (RedisSerializer<T>) template.getValueSerializer(), keys,
                args);
    }
    
    ... 
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected byte[][] keysAndArgs(RedisSerializer argsSerializer, List<K> keys, Object[] args) {
        final int keySize = keys != null ? keys.size() : 0;
        byte[][] keysAndArgs = new byte[args.length + keySize][];
        int i = 0;
        if (keys != null) {
            for (K key : keys) {
                if (keySerializer() == null && key instanceof byte[]) {
                    keysAndArgs[i++] = (byte[]) key;
                } else {
                    keysAndArgs[i++] = keySerializer().serialize(key);
                }
            }
        }
        for (Object arg : args) {
            if (argsSerializer == null && arg instanceof byte[]) {
                keysAndArgs[i++] = (byte[]) arg;
            } else {
                keysAndArgs[i++] = argsSerializer.serialize(arg);
            }
        }
        return keysAndArgs;
    }

顯然, key 與 args 都是有使用 redisTemplate 序列化進(jìn)行處理.

關(guān)于多個(gè)序列化工具的問(wèn)題,

有時(shí)候,我們想對(duì)key 與值采用不同的序列化工具, 如 key , 使用 string 序列化, value 使用 json 序列化, 從代碼上看, 需要重寫
redisTemplate

另外, 如果想在 lua 腳本中使用 json, 可以使用全局變量 cjson


local value = { true, { foo = 'mindasset', joo = 'java' } }
local json_text = cjson.encode(value)

return json_text

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程,因...
    小菜c閱讀 7,295評(píng)論 0 17
  • Redis 數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)介 Redis 可以存儲(chǔ)鍵與5種不同數(shù)據(jù)結(jié)構(gòu)類型之間的映射,這5種數(shù)據(jù)結(jié)構(gòu)類型分別為Stri...
    DreamerRzc閱讀 237,458評(píng)論 26 273
  • Nginx API for Lua Introduction ngx.arg ngx.var.VARIABLE C...
    吃瓜的東閱讀 6,052評(píng)論 0 5
  • 有人會(huì)問(wèn):“命運(yùn)是否掌握在自己手里?”我會(huì)毅然決然的回答他:“是的?!? 有一句話說(shuō)得好:“人定勝天?!泵\(yùn)就像彈...
    半夢(mèng)鳶尾閱讀 437評(píng)論 0 1

友情鏈接更多精彩內(nèi)容