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"
image

示例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
image

示例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的值
image

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命令获取值并转换为数字,最后比较大小并返回结果
posted @ 2026-01-14 16:24  Jing61  阅读(1)  评论(0)    收藏  举报