Redis 及 Spring Boot 使用 Lua 脚本详解
Redis 及 Spring Boot 使用 Lua 脚本详解
Lua基础语法参考
Lua基础语法可参考菜鸟教程的详细教程:Lua 教程 | 菜鸟教程
Redis执行Lua脚本的核心命令:eval
命令格式
eval lua-script key-num [key1 key2 key3 ...] [value1 value2 value3 ...]
参数说明
lua-script:待执行的Lua脚本内容key-number:指定参数中key的数量,注意:Redis中key参数的索引从1开始[key1 key2 key3 ...]:作为key的参数列表,传递给Lua脚本,可选参数[value1 value2 value3 ...]:非key类型的参数列表,传递给Lua脚本,可选参数
Redis执行Lua脚本示例
示例1:返回字符串
eval "return 'hello redis'" 0
执行效果:返回字符串 "hello redis"

示例2:执行set命令设置键值对
127.0.0.1:6379> eval "redis.call('set', KEYS[1], ARGV[1])" 1 com:username:10 peppa
(nil)
127.0.0.1:6379> keys *
1) "com:username:10"
说明:通过redis.call()调用Redis的set命令,将key为com:username:10的值设为peppa

示例3:执行get命令获取键值
127.0.0.1:6379> eval "return redis.call('get', KEYS[1])" 1 com:username:10
"peppa"
说明:通过redis.call()调用Redis的get命令,获取key为com:username:10的值

SpringBoot整合Redis使用Lua脚本
编写Lua脚本文件
在resources目录下创建test.lua文件,脚本内容如下:
-- 设置两个key的值
redis.call('set', KEYS[1], ARGV[1])
redis.call('set', KEYS[2], ARGV[2])
-- 获取两个key的值并转换为数字类型
local number1 = tonumber(redis.call('get', KEYS[1]))
local number2 = tonumber(redis.call('get', KEYS[2]))
-- 比较两个数字大小并返回结果
if number1 > number2 then
return 1
elseif number1 < number2 then
return -1
else
return 0
end
SpringBoot代码实现
测试代码
package com.springboot;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import java.util.List;
@SpringBootTest
public class RedisTest {
// 注入RedisTemplate
@Autowired
private RedisTemplate<String, Object> template;
@Test
public void lua() {
// 加载resources目录下的test.lua脚本
var resource = new ClassPathResource("test.lua");
// 定义RedisScript,指定返回类型为Long
RedisScript<Long> script = RedisScript.of(resource, Long.class);
// 执行脚本:参数1为脚本对象,参数2为key列表,后续为非key参数
var result = template.execute(
script,
List.of("com:springboot:10", "com:springboot:20"), // KEYS[1]、KEYS[2]
10, 20 // ARGV[1]、ARGV[2]
);
// 输出比较结果
System.out.println((result == 1) ? "number1 > number2" : "number1 <= number2");
}
}
代码说明
ClassPathResource:用于加载类路径(resources目录)下的Lua脚本文件RedisScript.of():创建RedisScript对象,指定脚本资源和返回值类型template.execute():执行Lua脚本,参数依次为:脚本对象、key列表、非key参数- 脚本执行流程:先通过
redis.call()调用Redis的set命令设置两个key的值,再通过get命令获取值并转换为数字,最后比较大小并返回结果

浙公网安备 33010602011771号