Java ReidsTemplate 发送脚本给redis执行 简单例子

4 篇文章 0 订阅

redisTemplate可以发送一段脚本给redis,来调用redis的接口。

脚本准备

执行redis的脚本。对于脚本的学习可以参考官网的文章:https://redis.io/commands/eval

jar包准备

我们使用redisTemplate,它有发送执行脚本的接口(下面的代码来自spring-data-redis-1.8.1.RELEASE版本):

    public <T> T execute(RedisScript<T> script, RedisSerializer<?> argsSerializer, RedisSerializer<T> resultSerializer, List<K> keys, Object... args) {
        return this.scriptExecutor.execute(script, argsSerializer, resultSerializer, keys, args);
    }

实例

这里以执行zrange函数为例,发送“希望执行zrange”的脚本让redis去执行。

数据准备

先做个数据准备,在命令行中执行两个语句来插入数据(注意千万不要一起粘贴执行哦,分开执行):

zadd test 1 one
zadd test 8 eight

然后用zrange查询下:

zrange test 0 3

结果:

ceshi:0>zrange test 0 3
 1)  "one"
 2)  "eight"

脚本准备

接下来在redis的控制台执行下脚本:

eval "return redis.call(KEYS[1],KEYS[2],ARGV[1],ARGV[2])ceshi:0>" 2 zrange test 0 3

结果:

ceshi:0>eval "return redis.call(KEYS[1],KEYS[2],ARGV[1],ARGV[2])ceshi:0>" 2 zrange test 0 3
 1)  "one"
 2)  "eight"

没问题,接下来就是java的事情了

java编程

这里只粘贴重要代码,至于redisTemplate如何配置创建对象,相信广大的开发者朋友都会。

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;  

    public List<String> pageKeysByZrangeScript(String tableName, Long start, Long end) {
        String scriptStr = "return redis.call(KEYS[1],KEYS[2], KEYS[3], KEYS[4])";//这里用了4个KEYS,不用ARGV了,你可以用。不过用了的话,就注意redisTemplate.execute调用的时候,注意给最后一个参数传递argv的数组
        List<String> keys = new ArrayList<>();
        keys.add("zrange");
        keys.add(tableName);
        keys.add(start + "");
        keys.add(end + "");

        RedisSerializer redisSerializer = new StringRedisSerializer();
        DefaultRedisScript<ArrayList<String>> defaultRedisScript = new DefaultRedisScript(scriptStr, ArrayList.class);
        ArrayList<String> result = redisTemplate.execute(defaultRedisScript, new Jackson2JsonRedisSerializer(ArrayList.class), redisSerializer,
                keys, new ArrayList<>());//这里因为用的4个KEYS,没用ARGV,所以传入一个空的ARGV的List

        System.out.println(result);

        return result;
    }

说明:

1. redisTemplate会将我们定义好的语句发送给redis,执行“”eval“”。

2. 这里比较麻烦的是:

DefaultRedisScript的创建以及redisTemplate.execute执行的时候传入的序列化和反序列化实例

     2.1 首先,因为查询的结果是一堆字符串的列表,因此这列DefaultRedisScript的类型为List<String>

     2.2 然后,execute函数:

        2.2.1. 第一个参数是脚本,直接传入即可。

        2.2.2. 第二个参数是我们传入的数据的序列化器(比如,看上面我的代码,keys对象不是一个String的list么),我们转入的是list,因此用类型为ArrayList的Jackson2JsonRedisSerializer序列化器

        2.2.3. 第三个参数,是redis返回数据的序列化器,因为我们返回的是一个元素为String的list,因此这列传入StringRedisSerializer实例,为什么是String而不是list的?原因源码中是这样解析的:

 protected <T> T deserializeResult(RedisSerializer<T> resultSerializer, Object result) {
        if (result instanceof byte[]) {
            return resultSerializer == null ? result : resultSerializer.deserialize((byte[])((byte[])result));
        } else if (!(result instanceof List)) {
            return result;
        } else {
            List results = new ArrayList();
            Iterator var4 = ((List)result).iterator();

            while(var4.hasNext()) {
                Object obj = var4.next();
                results.add(this.deserializeResult(resultSerializer, obj));
            }

            return results;
        }
    }

注意看,当Object result不是byte[]并且是List的时候,就会遍历其中的每一个元素,用序列化器去反序列化每一个元素。因此,我们传String的序列化器。

         2.2.4. 第四个参数,是我们的参数list,注意list中的参数对应 KEYS[1],KEYS[2], KEYS[3], KEYS[4] 的顺序。

         2.2.5. 第五个参数,这个是脚本执行语法中的ARGV[N]的数据,我们这里全部当做KEY来传递,因此全部写为KEYS,ARGV为空的list(注意不能传null!看源码就知道了)。

完成

这样就完成了基本的一个小例子。

看不懂的同学多半是卡在脚本的语法上了,注意仔细看官网文档即可,这里再粘贴出来官网地址:https://redis.io/commands/eval

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值