编码技巧——基于RedisTemplate的RedisClient实现、操作Lua脚本

1. 背景

在新公司的脚手架中开发,需要用到redis,发现没有封装好一套能集成各种常用命令、包括Lua脚本的方便使用的RedisTemplateClient,于是自己来实现下;

springboot整合redis之后,提供了操作redis的简便方式,可以通过通用对象RedisTemplate方式操作String,Hash,List,Set SortSet五大数据类型;

本次的实现就是基于Spring的RedisTemplate做的二次封装;

2. 代码

(1)RedisTemplate配置类

配置的关键是序列化器的配置;未配置好序列化器,会导致例如时间类、Json格式放入缓存中时,实际存放的值与预期不符,或是在获取值时出现预期之外的错误;

推荐下方的配置写法;

/**
 * Redis配置类
 */
@Configuration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties(MyRedisCacheProperties.class)
@AutoConfigureBefore(RedisAutoConfiguration.class)
@ConditionalOnProperty(prefix = "my.project.cache", name = "enabled", havingValue = "true", matchIfMissing = true)
public class RedisCacheAutoConfiguration {

    /**
     * 配置RedisTemplate
     *
     * @param factory Redis连接工厂
     * @return RedisTemplate<String, Object>
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = "spring.cache.type", havingValue = "redis")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(factory);
        // 设置key的序列化器
        template.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化器
        // 使用Jackson 2,将对象序列化为JSON
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = this.getJackson2JsonRedisSerializer();
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jackson2JsonRedisSerializer);

        return template;
    }

    /**
     * 获取Jackson2Json序列器
     *
     * @return Jackson2JsonRedisSerializer
     */
    protected Jackson2JsonRedisSerializer<Object> getJackson2JsonRedisSerializer() {
        // 使用Jackson 2,将对象序列化为JSON
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer =
                new Jackson2JsonRedisSerializer<>(Object.class);
        jackson2JsonRedisSerializer.setObjectMapper(this.getObjectMapper());

        return jackson2JsonRedisSerializer;
    }

    /**
     * 获取JSON对象映射器
     *
     * @return ObjectMapper
     */
    protected ObjectMapper getObjectMapper() {
        // json转对象类,不设置默认的会将json转HashMap
        ObjectMapper objectMapper = JacksonUtils.newObjectMapper();
        // 设置序列化时,保留对象的全类名,这样反序列化时就不用指定类型了
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.WRAPPER_ARRAY);
        return objectMapper;
    }

}

(2)RedisClient的二次封装

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * redisTemplate工具类 提供安全的redis操作命令
 */
@Slf4j
@Service
public class RedisService {

    private static final RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer();
    private static final RedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    // =============================common============================

    /**
     * 指定缓存失效时间
     *
     * @param key     键
     * @param seconds 时间(秒)
     */
    public void expire(String key, long seconds) {
        if (seconds > 0) {
            redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
        } else {
            throw new IllegalArgumentException("设置的redis过期时间应大于0! [badParam=" + seconds + "]");
        }
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long ttl(String key) {
        return Objects.requireNonNull(redisTemplate.getExpire(key, TimeUnit.SECONDS));
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }

    /**
     * 删除key
     *
     * @param key 可以传一个值 或多个
     */
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
                log.warn("删除redisKey成功 [key={}]", key[0]);
            } else {
                List<String> keys = Arrays.asList(key);
                redisTemplate.delete(keys);
                log.warn("批量删除redisKey成功 [keys={}]", JSON.toJSONString(keys));
            }
        }
    }

    // ============================Lua=============================

    /**
     * 执行lua脚本 脚本返回值必须为number
     *
     * @param luaScript
     * @param keys
     * @param args      为空时传Collections.emptyList()
     * @return
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public Long evalLua(String luaScript, List<String> keys, List<String> args) {
        // 利用泛型擦除
        RedisScript script = new DefaultRedisScript<>(luaScript, Long.class);
        Object execute = redisTemplate.execute(script, stringRedisSerializer, fastJsonRedisSerializer, keys, args.toArray());
        return (Long) execute;
    }

    /**
     * 执行lua脚本 脚本返回值必须为jsonString
     *
     * @param luaScript
     * @param keys
     * @param args      为空时传Collections.emptyList()
     * @return 返回类型
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public String evalLuaForJsonVal(String luaScript, List<String> keys, List<String> args) {
        // 利用泛型擦除
        RedisScript script = new DefaultRedisScript<>(luaScript, String.class);
        Object execute = redisTemplate.execute(script, stringRedisSerializer, fastJsonRedisSerializer, keys, args.toArray());
        return String.valueOf(execute);
    }

    /**
     * 执行lua脚本 脚本返回值必须为string 注意使用tostring函数或数值常量加单引号如'const'
     *
     * @param luaScript
     * @param keys
     * @param args      为空时传Collections.emptyList()
     * @return 返回类型
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public String evalLuaForStringVal(String luaScript, List<String> keys, List<String> args) {
        // 利用泛型擦除
        RedisScript script = new DefaultRedisScript<>(luaScript, String.class);
        Object execute = redisTemplate.execute(script, stringRedisSerializer, stringRedisSerializer, keys, args.toArray());
        return String.valueOf(execute);
    }

    // ============================String=============================

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public String get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key     键
     * @param value   值
     * @param seconds 时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public void setExpire(String key, String value, long seconds) {
        if (seconds > 0) {
            redisTemplate.opsForValue().set(key, value, seconds, TimeUnit.SECONDS);
        } else {
            set(key, value);
        }
    }

    /**
     * 递增
     *
     * @param key   键
     * @param delta 要增加几(大于0)
     * @return 递增后的结果
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new IllegalArgumentException("incr递增因子必须大于0");
        }
        return Objects.requireNonNull(redisTemplate.opsForValue().increment(key, delta));
    }

    /**
     * 递减
     *
     * @param key   键
     * @param delta 要减少几(小于0)
     * @return 递减后的结果
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new IllegalArgumentException("decr递减因子必须大于0");
        }
        return Objects.requireNonNull(redisTemplate.opsForValue().increment(key, -delta));
    }

    // ================================Hash=================================

    /**
     * HashGet
     *
     * @param key     键 不能为null
     * @param hashKey 项 不能为null
     */
    public Object hget(String key, String hashKey) {
        return redisTemplate.opsForHash().get(key, hashKey);
    }

    /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key 键
     * @param map 对应多个键值
     */
    public void hmset(String key, Map<String, Object> map) {
        redisTemplate.opsForHash().putAll(key, map);
    }

    /**
     * HashSet 并设置时间 不保证原子性
     *
     * @param key     键
     * @param map     对应多个键值
     * @param seconds 时间(秒)
     */
    public void hmsetExpire(String key, Map<String, Object> map, long seconds) {
        redisTemplate.opsForHash().putAll(key, map);
        if (seconds > 0) {
            expire(key, seconds);
        }
    }

    /**
     * 向一张hash表中放入数据,hash如果不存在将创建hash
     *
     * @param key   键
     * @param item  项
     * @param value 值
     */
    public void hset(String key, String item, Object value) {
        redisTemplate.opsForHash().put(key, item, value);
    }

    /**
     * 向一张hash表中放入数据,hash如果不存在将创建hash 不保证原子性 原子性使用Lua脚本
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     */
    public void hsetExpire(String key, String item, Object value, long time) {
        redisTemplate.opsForHash().put(key, item, value);
        if (time > 0) {
            expire(key, time);
        }
    }

    /**
     * 删除hash表中的值
     *
     * @param key     键 不能为null
     * @param hashKey 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... hashKey) {
        redisTemplate.opsForHash().delete(key, hashKey);
    }

    /**
     * 判断hash表中是否有该项的值
     *
     * @param key     键 不能为null
     * @param hashKey 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String hashKey) {
        return redisTemplate.opsForHash().hasKey(key, hashKey);
    }

    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key   键
     * @param item  项
     * @param delta 要增加几(大于0)
     */
    public double hincr(String key, String item, long delta) {
        if (delta < 0) {
            throw new IllegalArgumentException("hincr递增因子必须大于0");
        }
        return redisTemplate.opsForHash().increment(key, item, delta);
    }

    /**
     * hash递减
     *
     * @param key   键
     * @param item  项
     * @param delta 要减少记(小于0)
     */
    public double hdecr(String key, String item, long delta) {
        if (delta < 0) {
            throw new IllegalArgumentException("hdecr递减因子必须大于0");
        }
        return redisTemplate.opsForHash().increment(key, item, -delta);
    }

    // ============================set=============================

    /**
     * 根据key获取Set中的所有值
     *
     * @param key 键
     */
    public Set<String> sGet(String key) {
        return redisTemplate.opsForSet().members(key);
    }


    /**
     * 根据value从一个set中查询,是否存在
     *
     * @param key   键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(key, value));
    }

    private String[] toStringArray(List<Object> values) {
        List<String> collect = values.stream().map(String::valueOf).collect(Collectors.toList());
        String[] valStrArray = new String[collect.size()];
        for (int i = 0; i < valStrArray.length; i++) {
            valStrArray[i] = collect.get(i);
        }
        return valStrArray;
    }

    /**
     * 将数据放入set缓存
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, List<Object> values) {
        return Objects.requireNonNull(redisTemplate.opsForSet().add(key, toStringArray(values)));
    }

    /**
     * 将set数据放入缓存
     *
     * @param key     键
     * @param seconds 时间(秒)
     * @param values  值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key, long seconds, List<Object> values) {
        long count = Objects.requireNonNull(redisTemplate.opsForSet().add(key, toStringArray(values)));
        if (seconds > 0)
            expire(key, seconds);
        return count;
    }

    /**
     * 获取set缓存的长度
     *
     * @param key 键
     */
    public long sGetSetSize(String key) {
        return Objects.requireNonNull(redisTemplate.opsForSet().size(key));
    }

    /**
     * 移除值为value的
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, List<Object> values) {
        return Objects.requireNonNull(redisTemplate.opsForSet().remove(key, values));
    }

    // ===============================list=================================

    /**
     * 获取list缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束 0 到 -1代表所有值
     */
    public List<String> lrange(String key, long start, long end) {
        return redisTemplate.opsForList().range(key, start, end);
    }

    /**
     * 获取list缓存的长度
     *
     * @param key 键
     */
    public long lsize(String key) {
        return Objects.requireNonNull(redisTemplate.opsForList().size(key));
    }

    /**
     * 通过索引 获取list中的值
     *
     * @param key   键
     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     */
    public String lGetIndex(String key, long index) {
        return redisTemplate.opsForList().index(key, index);
    }

    /**
     * item放入list缓存
     *
     * @param key   键
     * @param value 值
     */
    public void ladd(String key, String value) {
        redisTemplate.opsForList().rightPush(key, value);
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public long lpush(String key, List<String> value) {
        return Objects.requireNonNull(redisTemplate.opsForList().rightPushAll(key, value));
    }

    /**
     * 根据索引修改list中的某条数据
     *
     * @param key       键
     * @param index     索引
     * @param updateVal 值
     * @return
     */
    public void lUpdateIndex(String key, long index, String updateVal) {
        redisTemplate.opsForList().set(key, index, updateVal);
    }

}

注意操作Lua脚本时,一般脚本预期的返回值是数值型;如果需要返回字符串或Json字符串,需要特殊指定返回类型和序列化器;如下:

    // ============================Lua=============================

    /**
     * 执行lua脚本 脚本返回值必须为number
     *
     * @param luaScript
     * @param keys
     * @param args      为空时传Collections.emptyList()
     * @return
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public Long evalLua(String luaScript, List<String> keys, List<String> args) {
        // 利用泛型擦除
        RedisScript script = new DefaultRedisScript<>(luaScript, Long.class);
        Object execute = redisTemplate.execute(script, stringRedisSerializer, fastJsonRedisSerializer, keys, args.toArray());
        return (Long) execute;
    }

    /**
     * 执行lua脚本 脚本返回值必须为jsonString
     *
     * @param luaScript
     * @param keys
     * @param args      为空时传Collections.emptyList()
     * @return 返回类型
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public String evalLuaForJsonVal(String luaScript, List<String> keys, List<String> args) {
        // 利用泛型擦除
        RedisScript script = new DefaultRedisScript<>(luaScript, String.class);
        Object execute = redisTemplate.execute(script, stringRedisSerializer, fastJsonRedisSerializer, keys, args.toArray());
        return String.valueOf(execute);
    }

    /**
     * 执行lua脚本 脚本返回值必须为string 注意使用tostring函数或数值常量加单引号如'const'
     *
     * @param luaScript
     * @param keys
     * @param args      为空时传Collections.emptyList()
     * @return 返回类型
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public String evalLuaForStringVal(String luaScript, List<String> keys, List<String> args) {
        // 利用泛型擦除
        RedisScript script = new DefaultRedisScript<>(luaScript, String.class);
        Object execute = redisTemplate.execute(script, stringRedisSerializer, stringRedisSerializer, keys, args.toArray());
        return String.valueOf(execute);
    }

(3)Lua脚本相关

可参考之前的文章编码技巧——Lua脚本的应用,这里再次附上代码;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Properties;

/**
 * 文件加载类
 */
@Slf4j
public class FileLoaderUtils {

    /**
     * 读文件文本到String 根目录为resource
     *
     * @param fileName
     * @return
     */
    public static String loadFile2String(String fileName) {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        URL url = loader.getResource(fileName);
        if (url == null) {
            log.error("Cannot_locate_" + fileName + "_as_a_classpath_resource.");
            throw new RuntimeException("Cannot_locate_" + fileName + "_as_a_classpath_resource.");
        }
        try {
            return IOUtils.toString(url, StandardCharsets.UTF_8);
        } catch (IOException e) {
            log.error("读取文件内容为String失败! [fileName={}]", fileName, e);
            throw new RuntimeException("读取文件内容为String失败! [fileName=" + fileName + "]");
        }
    }

    /**
     * 读文件文本到Property 根目录为resource
     *
     * @param fileName
     * @return
     */
    public static Properties loadFile2Property(String fileName) {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream in = loader.getResourceAsStream(fileName);
        Properties properties = new Properties();
        try {
            properties.load(in);
            if (in != null) {
                in.close();
            }
        } catch (IOException e) {
            log.error("读取文件内容到Properties失败! [fileName={}]", fileName, e);
            throw new RuntimeException("读取文件内容到Properties失败! [fileName=" + fileName + "]");
        }
        return properties;
    }

}
/**
 * LuaScript注册类
 */
public class LuaScript {

    // 常用原子操作
    private static final String INCR_EXPIRE;
    private static final String DECR_EXPIRE;
    private static final String SETNX_EXPIRE;
    private static final String HSET_EXPIRE;
    private static final String INCRBY_EXPIRE;
    private static final String SET_EXPIRE;

    static {
        DECR_EXPIRE = FileLoaderUtils.loadFile2String("lua/decr_expire.lua");
        INCR_EXPIRE = FileLoaderUtils.loadFile2String("lua/incr_expire.lua");
        SETNX_EXPIRE = FileLoaderUtils.loadFile2String("lua/setnx_expire.lua");
        HSET_EXPIRE = FileLoaderUtils.loadFile2String("lua/hset_expire.lua");
        INCRBY_EXPIRE = FileLoaderUtils.loadFile2String("lua/incrby_expire.lua");
        SET_EXPIRE = FileLoaderUtils.loadFile2String("lua/set_expire.lua");
    }

    public static String incrExpireScript() {
        return INCR_EXPIRE;
    }

    public static String decrExpireScript() {
        return DECR_EXPIRE;
    }

    public static String setnxExpireScript() {
        return SETNX_EXPIRE;
    }

    public static String hsetExpireScript() {
        return HSET_EXPIRE;
    }

    public static String incrbyExpireScript() {
        return INCRBY_EXPIRE;
    }

    public static String setExpireScript() {
        return SET_EXPIRE;
    }

}

以上,希望能帮到你;

参考:

Springboot整合Redis使用RedisTemplate操作redis五大类型用法详解

RedisTemplate执行lua脚本抛出异常IllegalStateException - 简书

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: redistemplate可以执行lua脚本,可以通过以下步骤实现: 1. 创建一个RedisTemplate对象。 2. 通过RedisTemplate对象获取一个RedisConnection对象。 3. 通过RedisConnection对象执行lua脚本,可以使用RedisConnection的eval()方法。 4. eval()方法的参数包括lua脚本脚本中需要的参数。 5. 执行完毕后,可以通过eval()方法的返回值获取脚本执行结果。 例如: ``` RedisTemplate<String, String> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); String script = "return redis.call('get', KEYS[1])"; String result = connection.eval(script.getBytes(), ReturnType.VALUE, 1, "key".getBytes()); ``` 以上代码执行了一个简单的lua脚本,获取了Redis中key为"key"的值。 ### 回答2: redis是一个内存缓存数据库,可用于提高Web应用程序的性能。而lua是一种脚本语言,可以被嵌入到各种编程语言中,包括redisredistemplateredis的一个Java客户端,可以用于与redis进行交互。redistemplate提供了一个execute方法,用于执行lua脚本。 执行lua脚本可以有效地提高redis的性能。在执行许多redis命令的情况下,每个命令都需要进行网络延迟,这会对性能产生负面影响。但是,通过执行lua脚本,可以将多个redis命令打包在一起,从而减少网络延迟。此外,lua脚本还可以在服务端执行,从而减少客户端和服务端之间的数据传输量。 使用redistemplate执行lua脚本可以分为以下几步: 1.创建lua脚本 在执行lua脚本之前,需要创建脚本lua脚本是一段文本,其语法类似于其他脚本语言。在编写脚本时,需要使用redis提供的一些特殊命令,例如get/set等。这些命令与普通的redis命令略有不同,需要使用redis.call或redis.pcall等特殊命令来调用。此外,还可以定义一些函数,从而使脚本更具可读性。 2.使用redistemplate执行脚本 redistemplate提供了execute方法,用于执行lua脚本。execute方法有两个参数:RedisScript对象和RedisSerializer对象。RedisScript对象表示要执行的lua脚本,可以使用LuaScriptBuilder类来构建。RedisSerializer对象表示要使用的序列化程序,用于将参数转换为字节数组以及将结果转换回对象。默认情况下,redistemplate使用JdkSerializationRedisSerializer来序列化对象,但也可以使用其他序列化程序,例如Jackson2JsonRedisSerializer。 执行lua脚本的结果是一个Object类型的值,可以通过类型转换将其转换为所需的类型,例如String、List等。此外,还可以使用redis提供的一些命令获取更复杂的结果,例如evalsha命令可以获取lua脚本的SHA1哈希值,从而可以在之后的操作中更高效地使用这个脚本。 总的来说,通过使用redistemplate执行lua脚本,可以在redis实现更复杂的操作,从而提高应用程序的性能和可靠性。虽然lua脚本相对复杂一些,但学习好后会发现有很多用处。 ### 回答3: redistemplateRedis中的一个模板,在执行Lua脚本时可以使用它来提供更多的功能。 在Redis中使用Lua脚本可以实现一些比较复杂的操作,而redistemplate可以为这些操作提供更好的支持。例如,当需要操作Redis的键和值时,通常需要先对它们进行序列化和反序列化,这个过程比较繁琐,但redistemplate提供了这些操作的封装,使得操作起来更为简单。 使用redistemplate执行Lua脚本时,需要将脚本和参数都传递给redistemplate,然后由redistemplate将它们交给Redis进行执行。在执行完成后,redistemplate会返回脚本的执行结果,同时也会释放与此脚本相关的所有资源。 需要注意的是,在使用redistemplate执行Lua脚本时,应该确保脚本的安全性。因为Lua脚本具有比较强的执行能力,如果脚本存在安全漏洞,可能会导致Redis的数据丢失或其他安全问题。因此,在编写和执行Lua脚本时应该遵守最佳安全实践,避免脚本的恶意使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值