文章目录
Redis介绍
Redis 是目前业界使用最广泛的内存数据存储。相比 Mmcached,Redis 支持更丰富的数据结构,例如:字符串类型 string,哈希类型 hash,列表类型 list,集合类型 set,有序集合类型 sortedset等,同时支持数据持久化。除此之外,Redis 还提供一些类数据库的特性,比如事务,HA,主从库。而且Redis具有极高的性能,据官方提供测试数据,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ,可以说 Redis 兼具了缓存系统和数据库的一些特性,因此有着丰富的应用场景。
更多Redis介绍和常见操作可以查看我这篇文章:Redis相关知识汇总(下载安装、Redis常见数据类型、持久化、命令和客户端操作)
本文主要讲解SpringBoot整合Redis常见的数据结构。
使用IDEA构建项目,同时引入对应依赖
构建springboot项目引入相关依赖,对应的pom文件内容如下:
PS:快速构建SpringBoot项目可以查看我这篇:SpringBoot快速入门
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot</artifactId>
<groupId>com.zjq</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.zjq</groupId>
<artifactId>springboot-redis</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--lettuce需要添加如下配置-->
<!--<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>-->
<!--jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
配置Redis
说明:Spring Boot 1.0 默认使用的是 Jedis 客户端,2.0 替换成 Lettuce,但如果你从 Spring Boot 1.5.X 切换过来,几乎感受不大差异,这是因为 spring-boot-starter-data-redis
为我们隔离了其中的差异性。Lettuce 是一个可伸缩线程安全的 Redis 客户端,多个线程可以共享同一个 RedisConnection,它利用优秀 netty NIO 框架来高效地管理多个连接。
使用Jedis
或者Lettuce
,yml文件中的redis配置如下:
yaml
spring:
redis:
# Redis数据库索引(默认为0)
database: 0
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码(默认为空)
password: 123456
# jedis连接池配置
# jedis:
# pool:
# #最大连接数 (使用负值表示没有限制) 默认 8
# max-active: 8
# #最大阻塞等待时间(负数表示没限制) 默认-1
# max-wait: -1
# #最大空闲 默认8
# max-idle: 8
# #最小空闲 默认0
# min-idle: 0
# lettuce连接池配置
lettuce:
pool:
#最大连接数 默认8
max-active: 8
#最大阻塞等待时间(负数表示没限制)
max-wait: -1
#最大空闲 默认8
max-idle: 8
#最小空闲
min-idle: 0
timeout: 100000
server:
port: 17002
添加Redis序列化方法
SpringBoot 为我们提供了一个高度封装的RedisTemplate
类来操作redis的各个命令,开发者无需关心具体的客户端 api 问题,通过RedisTemplate
提供的方法,就可以操作redis,方便开发者可以无成本替换 java 客户端。
当我们存储对象的时候,RedisTemplate
默认采用的是 Jdk
提供的序列化工具库,该工具有个要求,缓存的对象必须显式实现序列化接口,才能保存。
由于默认的是二进制存储方式,可读性较差,通常情况下,我们会自定义RedisTemplate
的序列化策略,采用Jackson
将对象转成json,查询的时候将json转成对象。添加如下redis序列化配置:
java
/**
* 默认是JDK的序列化策略,这里配置redisTemplate采用的是Jackson2JsonRedisSerializer的序列化策略
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer<Object> jacksonSeial = new Jackson2JsonRedisSerializer<>(Object.class);
// 使用Jackson序列号对象
ObjectMapper objectMapper = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(objectMapper);
// 使用RedisTemplate对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 值采用json序列化
template.setValueSerializer(jacksonSeial);
// 使用StringRedisSerializer来序列化和反序列化redis的hash-key值
template.setHashKeySerializer(new StringRedisSerializer());
// 值采用json序列化
template.setHashValueSerializer(jacksonSeial);
//执行后续方法
template.afterPropertiesSet();
return template;
}
RedisTemplate 实操
通过开始的结束我们知道,Redis 提供的数据结构很丰富,支持字符串、哈希表、列表、集合、有序集合等数据类型的存储,RedisTemplate对这五种数据结构分别定义了不同的操作类,具体如下:
ValueOperations
:操作最简单的K-V数据ListOperations
:操作list类型的数据HashOperations
:操作hash类型的数据SetOperations
:操作set类型的数据ZSetOperations
:操作zset类型的数据
心跳检测连接情况
java
@SpringBootTest
public class RedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void redisConnectTest(){
//心跳检测连接情况
String pong = redisTemplate.getConnectionFactory().getConnection().ping();
System.out.println("pong="+pong);
}
}
存取K-V字符串数据(ValueOperations)
java
@Test
public void redisStringGetSetTest() throws InterruptedException {
// 设置值,默认不过期
redisTemplate.opsForValue().set("userName","共饮一杯无");
// 获取值
String userName = (String) redisTemplate.opsForValue().get("userName");
System.out.println("获取userName对应的值="+userName);
// 设置值并且设置2秒过期时间,过期之后自动删除
redisTemplate.opsForValue().set("verificationCode", "666888", 2, TimeUnit.SECONDS);
Thread.sleep(1000);
System.out.println("获取验证码过期时间(单位秒):" + redisTemplate.getExpire("verificationCode"));
System.out.println("获取验证码对应的值:" + redisTemplate.opsForValue().get("verificationCode"));
Thread.sleep(1000);
System.out.println("获取验证码对应的值:" + redisTemplate.opsForValue().get("verificationCode"));
// 删除key
Boolean result = redisTemplate.delete("userName");
System.out.println("删除userName结果:" + result);
}
执行结果:
存取K-V对象数据(ValueOperations)
java
/**
* @author zjq
* @Description:
*/
@Data
@ToString
public class Person{
private Long id;
private String name;
private Integer age;
}
java
/**
* Redis Object类型测试
* @throws Exception
*/
@Test
public void redisObjectTest() throws Exception {
// 设置对象值,并且2秒自动过期
Person person = new Person();
person.setName("共饮一杯无");
person.setId(1L);
person.setAge(18);
savePerson(person);
//获取对象值
Person personResult = getPerson(1L);
System.out.println(personResult.toString());
System.out.println("获取person过期时间(单位秒):" + redisTemplate.getExpire("person"));
//删除key
Boolean deleteValue = redisTemplate.delete("person");
System.out.println("删除person结果:" + deleteValue);
}
/**
* 将Person对象存入Redis,键为person:{id},过期时间为2秒
*
* @param person 待存储的Person对象
*/
public void savePerson(Person person) {
String key = "person:" + person.getId();
redisTemplate.opsForValue().set(key, person, 2, TimeUnit.HOURS);
}
/**
* 从Redis中获取Person对象,键为person:{id}
*
* @param id Person对象的唯一标识符
* @return 如果存在则返回对应的Person对象,否则返回null
*/
public Person getPerson(Long id) {
String key = "person:" + id;
return (Person) redisTemplate.opsForValue().get(key);
}
输出结果如下:
存取hash数据(HashOperations)
HashOperations接口用于操作Redis哈希(Hash data type),提供了一系列方法来处理哈希表中的键值对。
- 添加、更新、删除键值对
- put(K key, HK hashKey, HV value)
在指定key对应的哈希表中,将hashKey与value关联起来。如果已有相同hashKey,则更新其值。
- putAll(K key, Map<? extends HK, ? extends HV> m)
将m中的所有键值对批量添加到指定key对应的哈希表中。如果有键已存在,则更新其值。
- increment(K key, HK hashKey, long delta)
如果hashKey对应的值是整数类型,将该值增加delta。如果hashKey不存在,则将其设置为delta。
- increment(K key, HK hashKey, double delta)
如果hashKey对应的值是浮点数类型,将该值增加delta。如果hashKey不存在,则将其设置为delta。
- delete(K key, Object... hashKeys)
从指定key对应的哈希表中删除与给定hashKeys关联的所有键值对。
- 查询键值对
- get(K key, HK hashKey)
返回指定key对应的哈希表中hashKey所关联的值。如果不存在,返回null。
- multiGet(K key, Collection hashKeys)
返回指定key对应的哈希表中与给定hashKeys关联的所有值组成的列表。对于不存在的hashKey,对应位置的值为null。
- 查询哈希表信息
- size(K key)
返回指定key对应哈希表中的键值对数量。
- keys(K key)
返回指定key对应哈希表中所有hashKey组成的集合。
- entries(K key)
返回指定key对应哈希表中所有键值对(Map.Entry<HK, HV>)组成的集合。
存取内容案例如下:
代码案例:
java
/**
* Redis Hash类型测试
*/
@Test
public void redisHashTest() throws Exception {
// 向hash中添加数据
HashOperations<String, String, Integer> operations = redisTemplate.opsForHash();
//Hash 中新增元素。
operations.put("score", "张三", 2);
operations.put("score", "李四", 1);
operations.put("score", "王五", 3);
operations.put("score", "赵六", 4);
Boolean hasKey = operations.hasKey("score", "张三");
System.out.println("检查是否存在【score】【张三】:" + hasKey);
Integer value = operations.get("score", "张三");
System.out.println("获取【score】【张三】的值:" + value);
Set<String> keys = operations.keys("score");
System.out.println("获取hash表【score】所有的key集合:" + JSON.toJSONString(keys));
List<Integer> values = operations.values("score");
System.out.println("获取hash表【score】所有的value集合:" + JSON.toJSONString(values));
Map<String,Integer> map = operations.entries("score");
System.out.println("获取hash表【score】下的map数据:" + JSON.toJSONString(map));
Long delete = operations.delete("score", "李四");
System.out.println("删除【score】中key为【李四】的数据:" + delete);
Boolean result = redisTemplate.delete("score");
System.out.println("删除整个key:" + result);
}
执行结果:
存取列表数据(ListOperations)
ListOperations
是Spring Data Redis模块中用于操作Redis列表(List data type)的一个核心接口。它提供了丰富的API来执行常见的列表操作,如添加元素、查询元素、删除元素、移动元素等。以下是ListOperations接口中的一些常用方法及其说明:
常用方法:
- 添加元素
- rightPush(K key, V value)
将给定的value值作为新的尾元素添加到指定key对应的列表末尾。
- leftPush(K key, V value)
将给定的value值作为新的头元素添加到指定key对应的列表开头。
- rightPushAll(K key, V... values)
将一组values依次作为新的尾元素添加到指定key对应的列表末尾。
- leftPushAll(K key, V... values)
将一组values依次作为新的头元素添加到指定key对应的列表开头。
- 查询元素
- range(K key, long start, long end)
返回指定key对应列表中索引从start(包含)到end(不包含)之间的元素列表。索引从0开始。
- index(K key, long index)
返回指定key对应列表中索引为index的元素。索引从0开始。
- 删除元素
- remove(K key, long index)
删除指定key对应列表中索引为index的元素。索引从0开始。
- remove(K key, V value)
删除指定key对应列表中第一个匹配value的元素。
- trim(K key, long start, long end)
保留指定key对应列表中索引从start(包含)到end(包含)之间的元素,删除其余元素。
- 移动元素
- rightPopAndLeftPush(K sourceKey, K destinationKey)
从sourceKey对应列表的右侧弹出一个元素,并将其作为左侧元素添加到destinationKey对应列表。如果sourceKey列表为空,则返回null。
- leftPopAndRightPush(K sourceKey, K destinationKey)
从sourceKey对应列表的左侧弹出一个元素,并将其作为右侧元素添加到destinationKey对应列表。如果sourceKey列表为空,则返回null。
- 其他操作
- size(K key)
返回指定key对应列表中的元素数量。
- leftPop(K key)
从key对应列表的左侧弹出一个元素。如果列表为空,则返回null。
- rightPop(K key)
从key对应列表的右侧弹出一个元素。如果列表为空,则返回null。
- rightPopAndLeftPush(K sourceKey, K destinationKey, long timeout, TimeUnit unit)
从sourceKey对应列表的右侧弹出一个元素(阻塞最多timeout时间单位的unit),并将其作为左侧元素添加到destinationKey对应列表。如果在等待期间sourceKey列表为空,则返回null。
- leftPopAndRightPush(K sourceKey, K destinationKey, long timeout, TimeUnit unit)
从sourceKey对应列表的左侧弹出一个元素(阻塞最多timeout时间单位的unit),并将其作为右侧元素添加到destinationKey对应列表。如果在等待期间sourceKey列表为空,则返回null。
- 阻塞操作(带超时)
- blpop(K... keys, long timeout, TimeUnit unit)
从多个给定keys对应的列表中阻塞地左弹出元素(等待最多timeout时间单位的unit)。返回第一个非空列表的键值对。
- brpop(K... keys, long timeout, TimeUnit unit)
从多个给定keys对应的列表中阻塞地右弹出元素(等待最多timeout时间单位的unit)。返回第一个非空列表的键值对。
代码案例:
java
/**
* Redis List类型测试
*/
@Test
public void redisListTest() {
// 向列表中添加数据
ListOperations<String, Person> operations = redisTemplate.opsForList();
// 往List左侧插入一个元素
operations.leftPush("userList", new Person(2,"共饮一杯无",19));
operations.leftPush("userList", new Person(1,"共饮一杯无",18));
//往 List 右侧插入一个元素
operations.rightPush("userList", new Person(3,"共饮一杯无",20));
operations.rightPush("userList", new Person(4,"共饮一杯无",21));
// 获取List 大小
Long size = operations.size("userList");
System.out.println("获取列表总数:" + size);
//遍历整个List
List<Person> allPerson1 = operations.range("userList", 0, size);
System.out.println("遍历列表所有数据:" + JSON.toJSONString(allPerson1));
//遍历整个List,-1表示倒数第一个即最后一个
List<Person> allPerson2 = operations.range("userList", 0, -1);
System.out.println("遍历列表所有数据:" + JSON.toJSONString(allPerson2));
//从 List 左侧取出第一个元素,并移除
Object Person1 = operations.leftPop("userList", 200, TimeUnit.MILLISECONDS);
System.out.println("从左侧取出第一个元素并移除:" + Person1.toString());
//从 List 右侧取出第一个元素,并移除
Object Person2 = operations.rightPop("userList", 200, TimeUnit.MILLISECONDS);
System.out.println("从右侧取出第一个元素并移除:" + Person2.toString());
}
执行结果:
存取Set集合数据(SetOperations)
SetOperations 提供了一组方法,这些方法封装了 Redis Set 数据结构支持的所有核心操作,使得开发者能够轻松地执行添加、移除、查询、计数、交集、并集、差集等操作,而无需直接编写底层的 Redis 命令。它通常作为 RedisTemplate 对象的泛型方法调用结果返回,例如:
java
SetOperations<String, YourValueType> setOps = redisTemplate.opsForSet();
这里的 YourValueType 是您要存储在 Set 中的具体对象类型。
常用方法
以下是 SetOperations 接口中一些典型的方法及其用途:
- 基本操作
add(K key, V... values)
: 将一个或多个成员(values)添加到指定键(key)对应的集合中。如果成员已存在,则不会重复添加。remove(K key, Object... values)
: 从指定键(key)对应的集合中移除一个或多个给定的成员。如果成员不存在于集合中,此操作不影响集合。isMember(K key, Object o)
: 检查指定键(key)对应的集合中是否包含给定的成员(o)。返回 true 表示存在,false 表示不存在。members(K key)
: 返回指定键(key)对应集合中所有的成员。结果以 Set 类型返回,包含了集合内所有对象的完整列表。
- 集合间操作
difference(K key, K otherKey)
: 计算指定键(key)对应的集合与其他集合(otherKey)之间的差集,即返回存在于 key 集合但不在 otherKey 集合中的成员。difference(K key, Collection<K> otherKeys)
: 计算指定键(key)对应的集合与一组集合(otherKeys)之间的差集,返回存在于 key 集合但不在任何其他集合中的成员。union(K key, K otherKey)
: 计算指定键(key)对应的集合与其他集合(otherKey)之间的并集,即返回同时存在于两个集合或仅存在于其中一个集合中的所有成员。union(K key, Collection<K> otherKeys)
: 计算指定键(key)对应的集合与一组集合(otherKeys)之间的并集,返回同时存在于 key 集合和其他任意集合或仅存在于任一集合中的所有成员。intersect(K key, K otherKey)
: 计算指定键(key)对应的集合与其他集合(otherKey)之间的交集,即返回同时存在于两个集合中的成员。intersect(K key, Collection<K> otherKeys)
: 计算指定键(key)对应的集合与一组集合(otherKeys)之间的交集,返回同时存在于 key 集合和其他所有集合中的成员。
- 额外功能
move(K key, V value, K destKey)
: 将指定键(key)集合中的某个成员(value)移动到另一个集合(destKey)。如果成功移动,返回 true;否则(如成员不存在或目标集合已存在该成员),返回 false。pop(K key)
: 从指定键(key)对应的集合中随机移除并返回一个成员。集合大小减1。size(K key)
: 返回指定键(key)对应集合中成员的数量。randomMember(K key)
: 随机从指定键(key)对应的集合中返回一个成员,但不移除它。
以上方法涵盖了 Redis 集合类型的主要操作,利用 SetOperations 接口,开发人员可以在 Java 代码中高效、便捷地管理 Redis 集合数据,实现诸如数据存储、查询、统计、合并、过滤等功能,适用于社交网络中的好友关系
、标签系统
、唯一性检查
等多种应用场景。
代码案例:
java
/**
* Redis Set类型测试
*/
@Test
public void redisSetTest() throws Exception {
// 向集合中添加数据
SetOperations<String, String> operations = redisTemplate.opsForSet();
//向集合中添加元素,set元素具有唯一性
operations.add("city", "北京","上海", "广州", "深圳", "杭州");
Long size = operations.size("city");
System.out.println("获取集合总数:" + size);
//判断是否是集合中的元素
Boolean isMember = operations.isMember("city", "广州");
System.out.println("检查集合中是否存在指定元素:" + isMember);
Set<String> cityNames = operations.members("city");
System.out.println("获取集合所有元素:" + JSON.toJSONString(cityNames));
Long remove = operations.remove("city", "广州");
System.out.println("删除指定元素结果:" + remove);
//移除并返回集合中的一个随机元素
String cityName = operations.pop("city");
System.out.println("移除并返回集合中的一个随机元素:" + cityName);
}
执行结果:
存取有序集合数据(ZSetOperations)
ZSetOperations 提供了一组方法,封装了 Redis ZSet 数据结构支持的所有核心操作,包括添加成员、更新分数、按分数范围查询、按排名查询、计算聚合值、执行集合间的有序集合操作等。同样,它通常作为 RedisTemplate 对象的泛型方法调用结果返回:
java
ZSetOperations<String, YourValueType> zSetOps = redisTemplate.opsForZSet();
这里的 YourValueType 是您要存储在 ZSet 中的具体对象类型。
常用方法
以下是 ZSetOperations 接口中一些典型的方法及其用途:
- 基本操作
add(K key, V value, double score)
: 向指定键(key)对应的有序集合中添加一个成员(value),并赋予其指定的分数(score)。如果成员已存在,分数将被更新。remove(K key, Object... values)
: 从指定键(key)对应的有序集合中移除一个或多个给定的成员(values)。如果成员不存在于集合中,此操作不影响集合。score(K key, Object o)
: 获取指定键(key)对应的有序集合中指定成员(o)的分数。如果成员不存在,返回 null。rank(K key, Object o)
: 获取指定键(key)对应的有序集合中指定成员(o)的排名(索引位置)。排名按分数从小到大排列,第一个成员的排名为 0。如果成员不存在,返回 -1。reverseRank(K key, Object o)
: 获取指定键(key)对应的有序集合中指定成员(o)的反向排名(按分数从大到小排列)。第一个成员的反向排名为 0。如果成员不存在,返回 -1。range(K key, long start, long end)
: 根据排名区间获取指定键(key)对应的有序集合中的成员。返回指定范围内(包括 start 和 end)的成员列表,按分数从小到大排列。reverseRange(K key, long start, long end)
: 根据反向排名区间获取指定键(key)对应的有序集合中的成员。返回指定范围内(包括 start 和 end)的成员列表,按分数从大到小排列。rangeByScore(K key, double min, double max)
: 根据分数区间获取指定键(key)对应的有序集合中的成员。返回分数在 [min, max] 范围内的成员列表,按分数从小到大排列。
- 集合间操作
unionAndStore(K key, K otherKey, K destKey)
: 计算指定键(key)对应的有序集合与其他有序集合(otherKey)之间的并集,并将结果存储到新的有序集合(destKey)。返回并集成员数量。unionAndStore(K key, Collection<K> otherKeys, K destKey)
: 计算指定键(key)对应的有序集合与一组有序集合(otherKeys)之间的并集,并将结果存储到新的有序集合(destKey)。返回并集成员数量。intersectAndStore(K key, K otherKey, K destKey)
: 计算指定键(key)对应的有序集合与其他有序集合(otherKey)之间的交集,并将结果存储到新的有序集合(destKey)。返回交集成员数量。intersectAndStore(K key, Collection<K> otherKeys, K destKey)
: 计算指定键(key)对应的有序集合与一组有序集合(otherKeys)之间的交集,并将结果存储到新的有序集合(destKey)。返回交集成员数量。
- 额外功能
count(K key, double min, double max)
: 返回指定键(key)对应的有序集合中,分数在 [min, max] 范围内的成员数量。incrementScore(K key, V value, double delta)
: 为指定键(key)对应的有序集合中指定成员(value)的分数增加(或减少,如果 delta 为负数)指定的数值(delta)。size(K key)
: 返回指定键(key)对应有序集合中成员的数量。rangeWithScores(K key, long start, long end)
: 类似于 range 方法,但除了返回成员列表外,还同时返回每个成员的分数。reverseRangeWithScores(K key, long start, long end)
: 类似于 reverseRange 方法,但除了返回成员列表外,还同时返回每个成员的分数。rangeByScoreWithScores(K key, double min, double max)
: 类似于 rangeByScore 方法,但除了返回成员列表外,还同时返回每个成员的分数。
与 SetOperations 的差异
SetOperations:
- 适用于无序、不重复的成员集合。
- 成员之间没有额外的关联数据,仅凭成员本身进行增删查操作。
- 不支持分数概念,无法根据特定条件(如分数范围、排名)进行查询或排序。
- 不支持集合间的并集、交集操作时保留成员的原始顺序或按分数排序的结果。
ZSetOperations:
- 适用于有序、不重复的成员集合,每个成员关联一个分数。
- 成员的增删查操作基于成员及其分数进行。
- 支持根据分数范围、排名(正序或逆序)进行精确查询。
- 集合间的并集、交集操作可以保留成员的原始顺序(按分数排序),并可将结果存储为新的有序集合。
- 提供了更新成员分数、获取成员分数、按分数增量调整分数等与分数相关的特有方法。
总结来说,ZSetOperations 在保持成员唯一性的基础上,增加了分数属性和排序功能,提供了更丰富的查询方式和集合间操作,适用于需要对集合元素进行排序、评分、排名等复杂场景,如排行榜
、带权重的关系存储
等。而 SetOperations 则专注于简单、无序的集合管理,适用于需要快速判断成员是否存在、执行集合间基础操作(如并集、交集、差集)等场景。
代码案例:
java
/**
* Redis ZSet类型测试
*/
@Test
public void redisZSetTest() throws Exception {
// 向有序集合中添加数据
ZSetOperations<String, String> operations = redisTemplate.opsForZSet();
//向有序集合中添加元素,set元素具有唯一性
operations.add("userName", "zhangsan", 100);
operations.add("userName", "lisi", 95);
operations.add("userName", "wangwu", 75);
operations.add("userName", "zhaoliu", 85);
//获取变量指定区间的元素。0, -1表示全部
Set<String> ranges = operations.range("userName", 0, -1);
System.out.println("获取有序集合所有元素:" + JSON.toJSONString(ranges));
Set<String> byScores = operations.rangeByScore("userName", 85, 100);
System.out.println("获取有序集合所有元素(按分数从小到大):"+ JSON.toJSONString(byScores));
Long zCard = operations.zCard("userName");
System.out.println("获取有序集合成员数: " + zCard);
Long remove = operations.remove("userName", "zhaoliu");
System.out.println("删除某个成员数结果: " + remove);
Set<String> ranges1 = operations.range("userName", 0, -1);
System.out.println("获取有序集合所有元素:" + JSON.toJSONString(ranges1));
}
执行结果:
Redis不同数据类型使用场景
本文主要讲解了SpringBoot整合Redis的操作,和RedisTemplate针对不同数据类型的一些场景和说明。总结下每种数据类型都有其独特的特性和适用场景,以下是它们的简要介绍及典型使用场景:
- String(字符串)
特性: 最基本的数据类型,可以存储任何类型的数据,包括数字、文本、图片等,支持多种操作如追加、截取、自增等。
使用场景:
计数器
:如网页访问计数、点赞数等。- 缓存存储:存储简单的键值对数据,如用户会话信息、配置信息等。
- 发布/订阅通道中的消息标识符。
- Hash(哈希)
特性: 存储键值对集合,每个哈希可以存储多个字段-值对,适合存储对象
。
使用场景:
- 用户信息存储:存储用户配置、用户资料等,每个字段对应用户的一个属性。
- Session存储:将用户的会话信息作为一个整体存储。
- 商品信息存储:每个商品作为一个哈希,包含价格、库存量等多个属性。
- List(列表)
特性: 有序的字符串列表,可以在列表两端进行高效的插入和删除操作。
使用场景:
消息队列
:实现简单的消息队列系统,新消息可以添加到列表尾部,消费时从头部取出。最近浏览记录
:存储用户最近浏览的商品ID列表。- 实现栈或队列数据结构。
- Set(集合)
特性: 无序且不重复的字符串集合,支持集合运算如并集、交集、差集等。
使用场景:
好友关系
:存储每个用户的好友列表,利用集合间的操作计算共同好友等。标签系统
:为文章或商品分配标签,快速查找拥有相同标签的内容。去重
:如统计网站访问的唯一IP地址。
- Sorted Set(有序集合)
特性: 类似集合,但每个成员都关联一个分数,根据分数排序。
使用场景:
排行榜
:如游戏得分排行榜,根据分数排序。时间线
:存储带有时间戳的事件,按时间顺序检索。优先级队列
:不仅存储任务,还能根据优先级(分数)进行处理。
这些数据类型的选择取决于具体的应用需求,如数据结构、查询模式、性能要求等。Redis的灵活性使其成为处理多种数据存储和访问模式的理想选择。
书籍推荐
鸟哥的Linux私房菜
《鸟哥的Linux私房菜------服务器架设篇(第三版修订)》是一本不可或缺的Linux服务器架设指导书,适合想要深入学习Linux服务器架设和管理的读者。本书不仅教授如何搭建服务器,还重点关注服务器的安全防护和维护,以及解决常见问题的策略。作者以系统基础和网络基础为起点,深入浅出地介绍了各种常见服务器的搭建方法。无论您是初学者还是有经验的用户,本书都将帮助您掌握Linux服务器的核心知识,为您的服务器提供稳定、安全的运行环境。
作者介绍
鸟哥,中国台湾成功大学环境工程系博士,就学期间由于研究需要接触到Linux操作系统,又因实验室交接需求而建立"鸟哥的Linux私房菜"网站。因个人喜好"絮叨",网站文章风格就此成形。曾任中国台湾多家知名Linux教育中心讲师,目前于中国台湾昆山科技大学资讯传播系教授Linux相关课程。专长是Linux操作系统、网站规划与维护、网络安全,兴趣是写作与阅读,研究方向是网络应用整合。
图书内容
本书的章节规划主要分为四篇:第一篇是服务器搭建前的进修专区,第二篇是主机的简易安全防护措施,第三篇是局域网内常见服务器的搭建,第四篇是常见Internet服务器的搭建。前两篇的内容都是关于基础的网络概念和实际网络配置,包括重要的网络自我检测和防火墙设置等。
服务器架设篇,第三版修订,主要是删除了一些过时软件,旧的网站,针对Linux系统版本进行了更新,内容大概有搭建服务器前的准备,网络的基本概念,局域网架构,Linux中常用的网络命令,网络故障排除,主机的安全防护措施,路由,防火墙,DHCP服务器,nfs服务器,nis服务器,ntp服务器,代理服务器,DNS服务器等等。
适合人群
具备一定的Linux基础知识,想进一步深入学习Linux服务器架设和管理的读者。
如何领书
本次本篇文章送书 🔥2本,公众号抽奖1本,累计3本
📆 活动时间:截止到 2024-05-13 10:00:00
🎁抽奖方式:评论区随机抽取2本,公众号抽取1本
🎉参与方式:
- 关注博主、点赞、收藏,评论:跟着鸟哥混,一天吃9顿
- 关注微信公众号《共饮一杯无》,发送:跟着鸟哥混 ,即可参与
或者微信扫描下方图片参与
🎉通知方式:活动结束后,会私信中奖粉丝的,各位注意查看私信哦!
也可以通过下方微信名片联系我。
自主购买
小伙伴也可以访问链接进行自主购买哦~
直达京东购买链接🔗:《鸟哥的Linux私房菜:服务器架设篇(第三版修订)》
本文内容到此结束了,
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位指出。
主页 :共饮一杯无的博客汇总👨💻保持热爱,奔赴下一场山海。🏃🏃🏃