话不多说先放脚本:
local argv = ARGV
local length = #argv
if length > 0 then local unpackArgs = {}
for i = 1, length - 1 do
table.insert(unpackArgs, argv[i])
end
if redis.call('exists', KEYS[1]) == 1 then
redis.call('del', KEYS[1])
redis.call('hset', KEYS[1], unpack(unpackArgs))
redis.call('expire', KEYS[1], argv[length])
return 1
else
redis.call('hset', KEYS[1], unpack(unpackArgs))
redis.call('expire', KEYS[1], ARGV[#ARGV])
return 2
end
end
2.直接String 执行LUA脚本
/**
* lua 脚本 实现物料key 的赋值
* @param hashKey 物料key
* @param fieldsAndValues lua 脚本参数
* @return
*/
public Long insertIntoHashWithExpireTime(String hashKey, Object... fieldsAndValues) {
Long result = null;
// unpack(ARGV)在Lua中是用来将数组解包成一系列单独的参数。
// ARGV[#ARGV]获取的是传递给脚本的最后一个参数(在 Lua 中,# 操作符用于获取表中的元素数量。因此,ARGV[#ARGV] 将返回 ARGV 表中的最后一个元素。)
// 请求案例:insertIntoHashWithExpireTimeIfKeyExists("myHash", "field1", "value1", "field2", "value2", 60);
String luaScript =
"\nlocal argv = ARGV \n" +
"local length = #argv \n"+
// 将1 - n-1 的入参写入新的数组
"if length > 0 then local unpackArgs = {} \n" +
"for i = 1, length - 1 do \n" +
" table.insert(unpackArgs, argv[i]) \n" +
"end\n" +
"if redis.call('exists', KEYS[1]) == 1 then \n" +
"\tredis.call('del', KEYS[1]) \n" +
"\tredis.call('hset', KEYS[1], unpack(unpackArgs)) \n" +
"\tredis.call('expire', KEYS[1], argv[length]) \n" +
"\treturn 1 \n" +
"else \n" +
"\tredis.call('hset', KEYS[1], unpack(unpackArgs)) \n" +
"\tredis.call('expire', KEYS[1], argv[length]) \n" +
"\treturn 2\n" +
"end \n" +
"end ";
log.info("luaScript:{}", luaScript);
try {
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.setResultType(Long.class);//返回类型是Long
redisScript.setScriptText(luaScript);
result = redisTemplate.execute(redisScript, Arrays.asList(hashKey), fieldsAndValues);
log.debug("redisEVALLuaScript result :{}", result);
} catch (Exception e) {
e.printStackTrace();
log.error("e:", e);
}
return result;
}
@Test
public void testLua(){
String hashKey = "testHash";
String field1 = "test3";
String value1 = "vv1";
String field2 = "test4";
String value2 = "vv2";
int expireTime = 10000;
// 插入数据并设置过期时间
redisUtils.insertIntoHashWithExpireTime(hashKey, field1, value1, field2, value2,expireTime);
}
最终结果: