SpringBoot高级篇Redis之List数据结构使用姿势

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 前面一篇博文介绍redis五种数据结构中String的使用姿势,这一篇则将介绍另外一个用的比较多的List,对于列表而言,用的最多的场景可以说是当做队列或者堆栈来使用了

前面一篇博文介绍redis五种数据结构中String的使用姿势,这一篇则将介绍另外一个用的比较多的List,对于列表而言,用的最多的场景可以说是当做队列或者堆栈来使用了


I. 基本使用



1. 序列化指定


前面一篇的操作都是直接使用的execute配合回调方法来说明的,其实还有一种更加方便的方式,即 opsForValue, opsForList,本文则以这种方式演示list数据结构的操作


所以在正式开始之前,有必要指定一下key和value的序列化方式,当不现实指定时,采用默认的序列化(即jdk的对象序列化方式),直接导致的就是通过redis-cli获取存储数据时,会发现和你预期的不一样


首先实现序列化类


public class DefaultSerializer implements RedisSerializer<Object> {
    private final Charset charset;
    public DefaultSerializer() {
        this(Charset.forName("UTF8"));
    }
    public DefaultSerializer(Charset charset) {
        Assert.notNull(charset, "Charset must not be null!");
        this.charset = charset;
    }
    @Override
    public byte[] serialize(Object o) throws SerializationException {
        return o == null ? null : String.valueOf(o).getBytes(charset);
    }
    @Override
    public Object deserialize(byte[] bytes) throws SerializationException {
        return bytes == null ? null : new String(bytes, charset);
    }
}
复制代码


其次定义RedisTemplate的序列化方式


@Configuration
public class AutoConfig {
    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, String> redis = new RedisTemplate<>();
        redis.setConnectionFactory(redisConnectionFactory);
        // 设置redis的String/Value的默认序列化方式
        DefaultSerializer stringRedisSerializer = new DefaultSerializer();
        redis.setKeySerializer(stringRedisSerializer);
        redis.setValueSerializer(stringRedisSerializer);
        redis.setHashKeySerializer(stringRedisSerializer);
        redis.setHashValueSerializer(stringRedisSerializer);
        redis.afterPropertiesSet();
        return redis;
    }
}
复制代码


2. 添加元素


对于list而言,添加元素常见的有两种,从左边加和从右边加,以lpush为例


/**
 * 在列表的最左边塞入一个value
 *
 * @param key
 * @param value
 */
public void lpush(String key, String value) {
    redisTemplate.opsForList().leftPush(key, value);
}
复制代码


3. 获取元素


既然是list,就是有序的,因此完全是可以向jdk的list容器一样,获取指定索引的值


/**
 * 获取指定索引位置的值, index为-1时,表示返回的是最后一个;当index大于实际的列表长度时,返回null
 *
 * @param key
 * @param index
 * @return
 */
public String index(String key, int index) {
    return redisTemplate.opsForList().index(key, index);
}
复制代码


与jdk中的List获取某个索引value不同的是,这里的index可以为负数,-1表示最右边的一个,-2则表示最右边的第二个,依次


4. 范围查询


这个查询就类似JDK容器中的List#subList了,查询指定范围的列表


/**
 * 获取范围值,闭区间,start和end这两个下标的值都会返回; end为-1时,表示获取的是最后一个;
 *
 * 如果希望返回最后两个元素,可以传入  -2, -1
 *
 * @param key
 * @param start
 * @param end
 * @return
 */
public List<String> range(String key, int start, int end) {
    return redisTemplate.opsForList().range(key, start, end);
}
复制代码


5. 列表长度


/**
 * 返回列表的长度
 *
 * @param key
 * @return
 */
public Long size(String key) {
    return redisTemplate.opsForList().size(key);
}
复制代码


6. 修改


更新List中某个下标的value,也属于比较常见的case了,


/**
 * 设置list中指定下标的值,采用干的是替换规则, 最左边的下标为0;-1表示最右边的一个
 *
 * @param key
 * @param index
 * @param value
 */
public void set(String key, Integer index, String value) {
    redisTemplate.opsForList().set(key, index, value);
}
复制代码


7. 删除


在接口中没有看到删除指定小标的元素,倒是看到可以根据value进行删除,以及控制列表长度的方法


/**
 * 删除列表中值为value的元素,总共删除count次;
 *
 * 如原来列表为 【1, 2, 3, 4, 5, 2, 1, 2, 5】
 * 传入参数 value=2, count=1 表示删除一个列表中value为2的元素
 * 则执行后,列表为 【1, 3, 4, 5, 2, 1, 2, 5】
 *
 * @param key
 * @param value
 * @param count
 */
public void remove(String key, String value, int count) {
    redisTemplate.opsForList().remove(key, count, value);
}
/**
 * 删除list首尾,只保留 [start, end] 之间的值
 *
 * @param key
 * @param start
 * @param end
 */
public void trim(String key, Integer start, Integer end) {
    redisTemplate.opsForList().trim(key, start, end);
}
复制代码


个人感觉在实际的使用中remove这个方法用得不太多;但是trim方法则比较有用了,特别是在控制list的长度,避免出现非常大的列表时,很有效果,传入的start/end参数,采用的是闭区间的原则



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
20天前
|
存储 消息中间件 NoSQL
Redis数据结构:List类型全面解析
Redis数据结构——List类型全面解析:存储多个有序的字符串,列表中每个字符串成为元素 Eelement,最多可以存储 2^32-1 个元素。可对列表两端插入(push)和弹出(pop)、获取指定范围的元素列表等,常见命令。 底层数据结构:3.2版本之前,底层采用**压缩链表ZipList**和**双向链表LinkedList**;3.2版本之后,底层数据结构为**快速链表QuickList** 列表是一种比较灵活的数据结构,可以充当栈、队列、阻塞队列,在实际开发中有很多应用场景。
|
25天前
|
存储 消息中间件 NoSQL
Redis 数据结构与对象
【10月更文挑战第15天】在实际应用中,需要根据具体的业务需求和数据特点来选择合适的数据结构,并合理地设计数据模型,以充分发挥 Redis 的优势。
54 8
|
24天前
|
存储 NoSQL Java
介绍下Redis 的基础数据结构
本文介绍了Redis的基础数据结构,包括动态字符串(SDS)、链表和字典。SDS是Redis自实现的动态字符串,避免了C语言字符串的不足;链表实现了双向链表,提供了高效的操作;字典则类似于Java的HashMap,采用数组加链表的方式存储数据,并支持渐进式rehash,确保高并发下的性能。
介绍下Redis 的基础数据结构
|
28天前
|
NoSQL 关系型数据库 MySQL
Redis 列表(List)
10月更文挑战第16天
17 2
|
1月前
|
消息中间件 存储 监控
redis 的List类型 实现 排行榜
【10月更文挑战第8天】
37 2
|
1月前
|
JSON NoSQL Java
springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)
该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。
|
1月前
|
NoSQL Java Redis
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
这篇文章介绍了如何使用Spring Boot整合Apache Shiro框架进行后端开发,包括认证和授权流程,并使用Redis存储Token以及MD5加密用户密码。
30 0
shiro学习四:使用springboot整合shiro,正常的企业级后端开发shiro认证鉴权流程。使用redis做token的过滤。md5做密码的加密。
|
1月前
|
消息中间件 存储 缓存
redis支持的数据结构
redis支持的数据结构
30 2
|
1月前
|
存储 分布式计算 NoSQL
大数据-40 Redis 类型集合 string list set sorted hash 指令列表 执行结果 附截图
大数据-40 Redis 类型集合 string list set sorted hash 指令列表 执行结果 附截图
27 3
|
20天前
|
存储 NoSQL 关系型数据库
Redis的ZSet底层数据结构,ZSet类型全面解析
Redis的ZSet底层数据结构,ZSet类型全面解析;应用场景、底层结构、常用命令;压缩列表ZipList、跳表SkipList;B+树与跳表对比,MySQL为什么使用B+树;ZSet为什么用跳表,而不是B+树、红黑树、二叉树