Redis的哈希操作multiGet()来从Redis中批量获取多个键对应的值

概要

Redis的哈希操作multiGet()来从Redis中批量获取多个键对应的值

例如:

获取当前角色放在缓存的菜单列表。

整体架构流程

  1. 使用hashOps.multiGet()方法从Redis中批量获取CommonConstant.ROLE_MENU_PERMISSIONS键对应的值。
  2. sysRoleIds.stream().map(String::valueOf).collect(Collectors.toSet())这部分代码是将sysRoleIds列表中的每个元素转换为字符串,并使用Collectors.toSet()方法将其收集到一个Set集合中。这个Set集合用于作为multiGet()方法的参数,表示要获取哪些键对应的值。
  3. 获取到的结果会存储在List<List<MenuDataItemVo>>类型的变量roleMenuIds中,其中每个内部列表表示一个角色对应的菜单权限。

代码片段:

 /**
     * 从缓存中获取角色绑定的菜单
     * @param sysRoleIds
     * @return
     */
    private List<MenuDataItemVo> listRoleMenuIdByCache(Set<Long> sysRoleIds) {
        HashOperations<String, String, List<MenuDataItemVo>> hashOps = redisTemplate.opsForHash();
        List<List<MenuDataItemVo>> roleMenuIds
                = hashOps.multiGet(CommonConstant.ROLE_MENU_PERMISSIONS, sysRoleIds.stream().map(String::valueOf)
                .collect(Collectors.toSet()));
        // 对结果进行处理,将 List<List<Integer>> 转为 List<Integer>
        return roleMenuIds.stream()
                .filter(p -> !CollectionUtils.isEmpty(p))
                .flatMap(List::stream).collect(Collectors.toList());
    }

技术细节

假设我们有以下角色ID列表和对应的菜单权限:

List<String> sysRoleIds = Arrays.asList("1", "2", "3");

我们假设在Redis中有一个名为ROLE_MENU_PERMISSIONS的哈希表,其中存储了每个角色对应的菜单权限。假设这个哈希表的结构如下:

Key: ROLE_MENU_PERMISSIONS

Field: "1" Value: [1, 2, 3]

Field: "2" Value: [4, 5, 6]

Field: "3" Value: []

现在,让我们来解释这段代码的逻辑:

  1. 使用hashOps.multiGet()方法从Redis中批量获取角色ID对应的菜单权限。这里会根据sysRoleIds列表中的元素,即["1", "2", "3"],去Redis中获取对应的值。

  2. 获取到的结果将会是一个List<List<MenuDataItemVo>>类型的roleMenuIds变量。在上述例子中,roleMenuIds将会是以下列表:

        [[MenuDataItemVo(id=1), MenuDataItemVo(id=2), MenuDataItemVo(id=3)],         [MenuDataItemVo(id=4), MenuDataItemVo(id=5), MenuDataItemVo(id=6)], []]

        3.接下来,代码会对结果进行处理。首先使用stream()方法将roleMenuIds转换为流(Stream)对象。

        4.然后使用filter()方法过滤掉空的菜单权限列表。在上述例子中,第三个列表是空的,所以会被过滤掉。

        5.使用flatMap()方法将每个内部列表展平为一个流(Stream)对象。在上述例子中,flatMap()方法会将前两个列表展平为一个包含所有菜单权限的流。

        6.最后,使用collect()方法将流中的元素收集到一个List<Integer>类型中。在上述例子中,最终返回的结果是:

        [1, 2, 3, 4, 5, 6]

小结

总结起来,这段代码的作用是从Redis中获取一组角色对应的菜单权限,并将其转换为一个扁平化的整数列表返回。在上述例子中,返回的结果是包含所有菜单权限的列表。

Redis是一个开源的内存数据存储系统,它支持多种数据结构,如字符串、哈希表、列表、集合等,并提供了丰富的操作命令。引用提到,Redis的单条命令是保证原子性的,但是Redis的事务是不保证原子性的,并且Redis事务没有隔离级别的概念。这意味着在一个事务执行的多个命令可能在其他客户端或线程断或修改。 引用指出,在RedisTemplate源码,默认使用的是jdk序列化器。这意味着在使用RedisTemplate的opsForValue().multiGet方法取时,会使用jdk序列化器对数据进行序列化和反序列化操作。 关于主从集群,Redis提供了复制功能,即将一个Redis实例的数据复制到其他实例。在主从集群,主节点负责写操作,而从节点负责读操作。通过主从集群可以提高Redis的可用性和性能。 综合以上信息,如果在使用redisTemplate.opsForValue().multiGet方法取时,取得的少了,可能有以下几个原因: 1. 数据在取之前被其他客户端修改或删除了,这是因为Redis事务的不保证原子性导致的。 2. 数据在序列化和反序列化过程发生了错误,这可能与使用的jdk序列化器有关。 3. 主节点没有及时同步数据到从节点,导致从节点上的数据不完整。这可能是由于网络延迟或其他原因导致的。 为了解决这个问题,可以采取以下措施: 1. 使用Redis的watch命令来监视取操作,确保在获取数据之前没有其他客户端对数据进行修改。 2. 尝试使用其他的序列化器,如Jackson或Fastjson,看是否能解决序列化和反序列化的问题。 3. 检查主从集群的配置和状态,确保主节点和从节点之间的数据同步正常。 希望以上信息对您有帮助。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Redis 详解](https://blog.csdn.net/weixin_43097056/article/details/117683359)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值