參考
api
- 使用
RedisScript<T>
- 使用
RedisTemplate.execute(RedisScript<T> script, List<K> keys, Object... args)
幾點需要關注的地方
redisScript.resultType
事實上精肃, DefaultScriptExecutor 拿到 connection.eval 的返回結果后誊抛, 只是判斷 redisScript.resultType 是否為空季稳,為空則直接返回為空,
如果不為空犁跪, 則根據(jù) 返回結果是 byte[] 還是 list 調(diào)用反序列化函數(shù)進行反序列化。
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ù)不會返回.
local result = { foo = "name", "breaker", "time" }
return result
關于參數(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
的 值
序列化進行處理.
關于多個序列化工具的問題,
有時候,我們想對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