Spring RedisTemplate 批量获取值的2种方式

本文介绍了两种在Redis中批量获取数据的方法:使用multiGet和PipeLine。这两种方法都通过减少网络往返次数来提高效率,其中PipeLine允许在一个连接上执行多条命令。文章还提到了查询结果与键的一一对应关系。
1、利用mGet
List<String> keys = new ArrayList<>();
//初始keys
List<YourObject> list = this.redisTemplate.opsForValue().multiGet(keys);
2、利用PipeLine
List<YourObject> list = this.redisTemplate.executePipelined(new RedisCallback<YourObject>() {
    @Override
    public YourObject doInRedis(RedisConnection connection) throws DataAccessException {
        StringRedisConnection conn = (StringRedisConnection)connection;
        for (String key : keys) {
            conn.get(key);
        }
        return null;
    }
});
其实2者底层都是用到execute方法,multiGet在使用连接是没用到pipeline,一条命令直接传给Redis,Redis返回结果。而executePipelined实际上一条或多条命令,但是共用一个连接。
    /**
     * Executes the given action object within a connection that can be exposed or not. Additionally, the connection can
     * be pipelined. Note the results of the pipeline are discarded (making it suitable for write-only scenarios).
     *
     * @param <T> return type
     * @param action callback object to execute
     * @param exposeConnection whether to enforce exposure of the native Redis Connection to callback code
     * @param pipeline whether to pipeline or not the connection for the execution
     * @return object returned by the action
     */
    public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
        Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
        Assert.notNull(action, "Callback object must not be null");

        RedisConnectionFactory factory = getConnectionFactory();
        RedisConnection conn = null;
        try {

            if (enableTransactionSupport) {
                // only bind resources in case of potential transaction synchronization
                conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
            } else {
                conn = RedisConnectionUtils.getConnection(factory);
            }

            boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);

            RedisConnection connToUse = preProcessConnection(conn, existingConnection);

            boolean pipelineStatus = connToUse.isPipelined();
            if (pipeline && !pipelineStatus) { //开启管道
                connToUse.openPipeline();
            }

            RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
            T result = action.doInRedis(connToExpose);

            if (pipeline && !pipelineStatus) {// 关闭管道
                connToUse.closePipeline();
            }

            // TODO: any other connection processing?
            return postProcessResult(result, connToUse, existingConnection);
        } finally {

            if (!enableTransactionSupport) {
                RedisConnectionUtils.releaseConnection(conn, factory);
            }
        }
    }

还有一点,就是查询返回的结果,和键的顺序是一一对应的,如果没查到,会返回null值。




### 3.1 使用 `redisTemplate` 实现模糊匹配批量删除 在 Spring Data Redis 中,`redisTemplate` 提供了 `keys` 方法用于根据指定模式匹配所有符合条件的 key,然后通过 `delete` 方法一次性删除这些 key。此方式适用于数据量较小的场景,但需要注意 `keys` 命令在大规模数据下可能对性能造成影响。 以下是一个典型的实现方式: ```java public void deleteByPrefix(String prefix) { Set<String> keys = redisTemplate.keys(prefix); if (!CollectionUtils.isEmpty(keys)) { redisTemplate.delete(keys); } } ``` 该方法通过 `keys` 方法获取所有匹配的键集合,并使用 `delete` 方法进行批量删除。此方式适用于前缀较明确且匹配结果数量有限的场景[^1]。 --- ### 3.2 使用模糊匹配直接删除单个 key 若需根据特定模式直接删除 key,也可直接调用 `delete` 方法传入模式字符串。Spring Data Redis 的 `RedisTemplate` 支持直接传入带有通配符的 key 模式进行删除操作。 示例代码如下: ```java String keyPattern = "noteUserListenedPoi:*"; redisTemplate.delete(keyPattern); ``` 此方式在内部实现中会自动匹配所有符合 `noteUserListenedPoi:*` 模式的 key 并删除。虽然使用简单,但不适用于大规模数据,因其底层仍基于 `KEYS` 命令实现,可能造成 Redis 阻塞[^2]。 --- ### 3.3 使用 SCAN 替代 KEYS 避免阻塞 为了避免 `keys` 命令在大规模数据中引发性能问题,可以结合 `scan` 方法分批次获取匹配的 key,并逐批删除。这种方式能够有效降低对 Redis 服务的阻塞风险。 示例代码如下: ```java public void deleteByScan(String pattern) { ScanOptions options = ScanOptions.scanOptions().match(pattern).build(); Cursor<byte[]> cursor = redisTemplate.getConnectionFactory().getConnection().scan(options); while (cursor.hasNext()) { byte[] key = cursor.next(); redisTemplate.delete(new String(key)); } } ``` 该方法通过 `scan` 命令逐步遍历所有匹配的 key,避免一次性加载所有匹配项,适用于数据量较大的场景。 --- ### 3.4 注意事项与建议 - 在生产环境中,应优先使用 `SCAN` 替代 `KEYS` 进行模糊匹配,以避免 Redis 阻塞。 - 删除操作不可逆,建议在执行前确认 key 模式和匹配结果。 - 若需提高删除效率,可结合管道(Pipeline)机制,将多个删除命令合并发送。 - 对于高频调用的删除操作,建议封装为通用方法,提升代码复用性与可维护性。 ---
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值