redis-cli redisTemplate执行Lua脚本,解决redisTemplate.opsForSet().members获取数据问题

解决问题—问题描述

在使用redisTemplate.opsForSet().members(key)获取key String; value Set<Entity>数据时候出现如下问题。

Caused by: com.fasterxml.jackson.databind.exc.InvalidTypeIdException:
Missing type id when trying to resolve subtype of [simple type, class
java.lang.Object]: missing type id property ‘@Class’ at [Source:
(io.netty.buffer.ByteBufInputStream); line: 1, column: 322]

Could not resolve type id ‘xxx.xxx.Entity’ as a subtype of [simple
type, class java.lang.Object]: no such class found

github的issue中出现和我一样的问题
https://github.com/redisson/redisson/issues/1865

解决方式

在redis存放数据实体Entity数据时候,redis也把当前的Entity类全路径存放进去了。如果redis的value中的Entity类全路径 和取出映射的全限定名不一致就会报错。

redis存放的Entity类中的字段与取出数据时候映射的Entity类字段不一致也会报错。

解决方式,存进去的Entity路径和取出映射的全限定名要保持一致


redis-cli和redisTemplate执行Lua脚本
redis-cli执行Lua脚本

定义好Lua脚本

local poem_id = redis.call('get', KEYS[1]) 
return redis.call('get', 'poem_id_'..poem_id)

脚本意思:
指定一个key,通过这个key获取到内容poem_id,在根据获取到的内容poem_id作为第二行key,再次查询并返回结果。

Lua脚本写好了,把它组成redis-cli能够识别的命令。
eval是告诉redis-cli你需要执行脚本,字符串中是脚本内容,后面的数字1表示有几个key,最后是真正传入的key内容。
eval "local poem_id = redis.call('get', KEYS[1]) return redis.call('get', 'poem_id_'..poem_id)" 1 poem_verse_争似秦楼萧史伴

springboot的redisTemplate执行Lua脚本

直接上代码,注意的是 java代码key1 就是填充Lua脚本的 KEYS[1] 内容

String lua = "return redis.call('get', KEYS[1])";
System.out.println(lua);

DefaultRedisScript<String> rs = new DefaultRedisScript<String>();
//设置脚本
rs.setScriptText(lua);
//定义返回类型。注意如果没有这个定义,spring不会返回结果
rs.setResultType(String.class);
RedisSerializer<String> stringRedisSerializer = 
			redisTemplate.getStringSerializer();
//这里的key1就是Lua脚本的 KEYS[1] 内容
String key1 = "poem_verse_日长睡起";
//定义key
List<String> keyList = new ArrayList<String>();
keyList.add(key1);
String luaScriptResult = (String) redisTemplate.execute(rs, 
							stringRedisSerializer, 
							stringRedisSerializer, keyList);

RedisSerializer<String> stringRedisSerializer = redisTemplate.getStringSerializer() 是redis返回结果,然后对结果进行序列化处理。这里处理成string。
可能你存放的value不是string而是一个Entity。就是这样的

Entity luaScriptResult = 
	(Entity) redisTemplate.execute(rs, keyList);

luaScriptResult是执行出的结果

水平原因可能存在错误,希望指正 chenrui@marsdl.com

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值