需求:工作中使用kafka接收数据,需要批量对redis中的hash操作,而redisTemplate并没有提供相应的方法,里面对于批量插入操作,只有一个
public void putAll(K key, Map<? extends HK, ? extends HV> m) {
if (!m.isEmpty()) {
byte[] rawKey = this.rawKey(key);
Map<byte[], byte[]> hashes = new LinkedHashMap(m.size());
Iterator var5 = m.entrySet().iterator();
while(var5.hasNext()) {
Entry<? extends HK, ? extends HV> entry = (Entry)var5.next();
hashes.put(this.rawHashKey(entry.getKey()), this.rawHashValue(entry.getValue()));
}
this.execute((connection) -> {
connection.hMSet(rawKey, hashes);
return null;
});
}
}
这显然不是我想要的,我想要的是批量对1000个hash操作,而这样我还是要for循环走1000次连接。在网上找了半天没有找到对应的办法后,我参考这个写法,写了一个自己的方法。代码如下:
@SpringBootTest
class SpringbootRedisApplicationTests {
@Test
void contextLoads() {
RedisTemplate redisTemplate = (RedisTemplate) SpringContextUtil.getBean("redisTemplate");
RedisSerializer keySerializer = redisTemplate.getKeySerializer();
RedisSerializer hashKeySerializer = redisTemplate.getHashKeySerializer();
RedisSerializer hashValueSerializer = redisTemplate.getHashValueSerializer();
Map<String, Map<String, Object>> map = new HashMap<>();
Map<String, Object> aMap = new HashMap<>();
aMap.put("st",1);
aMap.put("time", "2021-12-1");
for (int i = 0; i < 1000; i++) {
map.put(i+"", aMap);
}
redisTemplate.executePipelined((RedisCallback<Map>) connection->{
Iterator<Map.Entry<String, Map<String, Object>>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Map<String, Object>> next = iterator.next();
byte[] rawKey = keySerializer.serialize(next.getKey());
Map<byte[], byte[]> hashes = new LinkedHashMap(next.getValue().size());
Iterator var5 = next.getValue().entrySet().iterator();
while(var5.hasNext()) {
Map.Entry<String, Object> entry = (Map.Entry)var5.next();
hashes.put(hashKeySerializer.serialize(entry.getKey()),
hashValueSerializer.serialize(entry.getValue()));
}
// 这里可以改成你想要的操作,比如删除或者根据条件对应操作之类的
connection.hMSet(rawKey, hashes);
}
return null;
});
}
}
我这是在测试类里面写的,同行们可以粘到自己的工具类里面去,传参是一个Map<String,Map<String,Object>>就行了,为了严谨,防止序列化出现问题,我又进行了取的测试
// 随便取出试用
Map map = (Map<String, String>)redisTemplate.opsForHash().entries("100");
System.out.println(map);
发现没有问题,这样我们就可以只用一次连接批量对hash操作了。
有疑问可以在评论区交流,作者看见会回复。
如需转载,请一定声明原处。