Springboot redis luttuce lua脚本 存储压缩的protobuf key:byte[] value:map<byte,byte[]>

注释部分是正常的map<string,value> 的方式,对该lua脚本进行了优化

复制代码
 /**
     *  lua 脚本 实现物料key 的赋值
     * @param hashKey 物料key
     * @param fieldsAndValues lua 脚本参数
     * @return
     */
    public Long insertIntoHashWithExpireTime(byte[] hashKey, Map<byte[], byte[]> fieldsAndValues, int expireTime) {
        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 ";
        String luaScript =
                "local argv = ARGV\n" +
                        "local length = #argv\n" +
                        "\n" +
                        "-- 检查是否有参数传入\n" +
                        "if length > 0 then\n" +
                        "    -- 创建一个新的表来存储键值对\n" +
                        "    local unpackArgs = {}\n" +
                        "\n" +
                        "    -- 从第一个参数开始处理\n" +
                        "    -- 将ARGV中的键值对转换为Lua表\n" +
                        "    for i = 1, length - 1, 2 do\n" +
                        "        table.insert(unpackArgs, argv[i])     -- 键\n" +
                        "        table.insert(unpackArgs, argv[i + 1]) -- 值\n" +
                        "    end\n" +
                        "\n" +
                        "    -- 获取过期时间\n" +
                        "    local expireTime = tonumber(argv[length])\n" +
                        "\n" +
                        "    -- 检查键是否存在\n" +
                        "    if redis.call('exists', KEYS[1]) == 1 then\n" +
                        "        -- 如果键存在,先删除旧的键\n" +
                        "        redis.call('del', KEYS[1])\n" +
                        "        -- 再设置新的键值对\n" +
                        "        for i = 1, #unpackArgs - 1, 2 do\n" +
                        "            redis.call('hset', KEYS[1], unpackArgs[i], unpackArgs[i + 1])\n" +
                        "        end\n" +
                        "        -- 设置过期时间\n" +
                        "        redis.call('expire', KEYS[1], expireTime)\n" +
                        "        return 1\n" +
                        "    else\n" +
                        "        -- 如果键不存在,直接设置新的键值对\n" +
                        "        for i = 1, #unpackArgs - 1, 2 do\n" +
                        "            redis.call('hset', KEYS[1], unpackArgs[i], unpackArgs[i + 1])\n" +
                        "        end\n" +
                        "        -- 设置过期时间\n" +
                        "        redis.call('expire', KEYS[1], expireTime)\n" +
                        "        return 2\n" +
                        "    end\n" +
                        "end";
        log.info("luaScript:{}", luaScript);
        try {
            // 将 Map 转换成有序的键值对列表
            // 创建参数列表
            List<byte[]> args = new ArrayList<>(fieldsAndValues.size() * 2 + 1);
            for (Map.Entry<byte[], byte[]> entry : fieldsAndValues.entrySet()) {
                args.add(entry.getKey());
                args.add(entry.getValue());
            }
            args.add(String.valueOf(expireTime).getBytes()); // 最后一个参数是过期时间

            DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
            redisScript.setResultType(Long.class);//返回类型是Long
            redisScript.setScriptText(luaScript);

            // 执行脚本
            result = protobufRedisTemplate.execute(redisScript,
                    Collections.singletonList(hashKey), // KEYS
                    args.toArray(new byte[0][])); // ARGV

            log.debug("redisEVALLuaScript result :{}", result);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("e:", e);
        }
        return result;
    }

有一说一,感谢大模型,这个完全是大模型给出的答案。

结果如下

相关推荐
仍然.2 小时前
Redis---缓存
数据库·redis·缓存
paopaokaka_luck2 小时前
基于springboot+vue的智慧家政管理系统(AI问答、 WebSocket实时沟通、ECharts运营分析、订单规则与服务追踪)
java·javascript·spring boot·数据分析·echarts·mybatis
阿森_dev3 小时前
2027 届毕设选题怎么选:30 个 Java 方向选题的实现难度排序
java·开发语言·spring boot·毕业设计·课程设计
计算机毕业设计杰瑞3 小时前
【计算机毕设精品】基于SpringBoot的一体化教务与学业质量管理系统的设计与实现,附源码_增删改查_java项目_可完美运行部署_网站项目
java·spring boot·课程设计
大侠归来5 小时前
Spring Boot 2.1 → 3.5 迁移推演:从实战出发的完整路线图
java·spring boot·后端
仍然.5 小时前
Redis---分布式锁
数据库·redis·分布式
Sweet锦5 小时前
jDCS 开源项目:面向工业现场的 Modbus RTU 数据采集基础框架
java·spring boot·物联网·开源
海马5 小时前
Spring Boot 开发知识整理
java·spring boot·后端
谢亮_vipxieliang6 小时前
Spring Boot 3.x 从零开始——环境搭建与第一个 REST 项目
java·spring boot·后端
FYKJ_20106 小时前
django个性化新闻推荐35173-计算机课程设计、毕业设计
java·spring boot·后端·python·架构·django·课程设计