redisTemplate批量新增hash

在工作中遇到Kafka接收到数据后需要批量处理Redis中的Hash,发现redisTemplate缺少直接支持的方法。通过自行编写代码,实现了使用pipeline进行1000次Hash操作,从而避免多次连接。测试验证了方法的正确性,可以将此代码段应用于工具类中,实现高效批量处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:工作中使用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操作了。

有疑问可以在评论区交流,作者看见会回复。

如需转载,请一定声明原处。

### Redis Hash 数据类型的使用方法及示例 #### 1. Redis Hash 数据类型简介 Redis 中的 `Hash` 是一种键值对集合的数据结构,适合存储对象属性及其对应值。通过 `redisTemplate.opsForHash()` 方法可以获得用于操作 Redis Hash 的工具类 `HashOperations`,从而实现各种功能。 #### 2. 添加字段到 Hash 表 可以通过命令 `HSET` 将字段添加到指定的 Hash 表中。如果字段已存在,则更新其值;如果不存在,则新增该字段并赋值[^1]。 ```bash redis> HSET myhash field1 "foo" (integer) 1 ``` #### 3. 获取 Hash 字段中的值 利用 `HGET` 命令可以从 Hash 表中获取特定字段的值。如果字段不存在,则返回 `(nil)`[^2]。 ```bash redis> HGET myhash field1 "foo" redis> HGET myhash field2 (nil) ``` #### 4. 判断字段是否存在 使用 `HEXISTS` 可以判断某个字段是否存在于指定的 Hash 表中。返回值为整数型布尔值:`1` 表示存在,`0` 表示不存在[^3]。 ```bash redis> HEXISTS myhash field1 (integer) 1 redis> HEXISTS myhash field2 (integer) 0 ``` #### 5. 删除字段 要从 Hash 表中移除一个或多个字段,可使用 `HDEL` 命令。 ```bash redis> HDEL myhash field1 (integer) 1 ``` #### 6. 批量操作 - **获取所有字段和值** 使用 `HGETALL` 能够一次性取出整个 Hash 表的内容,结果是一个交替排列的数组形式。 ```bash redis> HSET myhash field1 "foo" (integer) 1 redis> HSET myhash field2 "bar" (integer) 1 redis> HGETALL myhash 1) "field1" 2) "foo" 3) "field2" 4) "bar" ``` - **获取所有字段名** 如果只需要字段名称列表而不需要它们的具体值,可以调用 `HKEYS` 来完成此任务。 ```bash redis> HKEYS myhash 1) "field1" 2) "field2" ``` - **获取所有字段值** 若要提取所有的字段值而不关心具体的字段名,可以用 `HVALS` 命令来达成目标。 ```bash redis> HVALS myhash 1) "foo" 2) "bar" ``` #### 7. 计算字段数量 为了统计某 Hash 表内的字段总数,可以借助于 `HLEN` 命令。 ```bash redis> HLEN myhash (integer) 2 ``` --- ### Java 示例代码 以下是基于 Spring Data Redis 提供的一个简单例子,展示如何使用 `redisTemplate.opsForHash()` 进行基本操作: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; public class RedisHashExample { @Autowired private RedisTemplate<String, String> redisTemplate; public void demo() { // 初始化 HashOperations 对象 HashOperations<String, Object, Object> hashOps = redisTemplate.opsForHash(); // 设置单个字段 hashOps.put("myhash", "field1", "foo"); // 批量设置字段 Map<Object, Object> map = new HashMap<>(); map.put("field2", "bar"); map.put("field3", "baz"); hashOps.putAll("myhash", map); // 获取单个字段值 System.out.println(hashOps.get("myhash", "field1")); // 获取所有字段和值 System.out.println(hashOps.entries("myhash")); } } ``` ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值