Redis 使用ZSet数据结构保存JSON格式的数据,在入到Redis后反序列化时发生了错误:
原因是到Redis中存储时,给每一个字段前加上了反斜杠,不能直接使用JSON直接反序列化。
可以使用JSON.parse()方法在反序列化之前,对于字符串解析一下即可。
int setNum = (page - 1) * size / 20000;int from = (page - 1) * size % 20000;
List<Object> zSetByRange = redisUtil.getZSetByRange("redis keyName",from,from+size-1);Object parse = JSON.parse(zSetByRange.toString());
list= JSON.parseArray(JSON.toJSONString(parse), 反序列化的类.class);
redisUtil.getZSetByRange:等价于以下代码段
public List<Object> getZSetByRange(String key, int start, int end){ Set<Object> range = redisTemplate.opsForZSet().range(key, start, end);
return new ArrayList<>(range);
}
报错信息:
com.alibaba.fastjson.JSONException: field null expect '[', but string, pos 2509, line 1, column 2510"[{\"..............
下附一个Redis Template API支持的批量插入的代码模板:
/**批量保存至Redis*/public <T>void saveDataToRedis(List<T> list,String setName) {
RedisSerializer<String> keySerializer = (RedisSerializer<String>)redisTemplate.getKeySerializer();
RedisSerializer<String> valueSerializer = (RedisSerializer<String>)redisTemplate.getValueSerializer();
//获取插入开始时间戳
long startTime = System.currentTimeMillis();
redisTemplate.executePipelined((RedisCallback<String>) connection -> {
for (int i = 0; i < list.size(); i++) {
connection.zSetCommands().zAdd(keySerializer.serialize(setName),i,valueSerializer.serialize(JSON.toJSONString(list.get(i))));
}
//设置超时时间
connection.expire(keySerializer.serialize(setName), 3600L);
return null;
});
//获取插入结束时间戳,打印日志
long endTime = System.currentTimeMillis();
long costTime = endTime - startTime;
log.info(">>>>>>saveDataToRedis add into redis by using pipeline for loop spent->" + costTime);
}