记录:402
场景:在Spring Boot微服务使用RedisTemplate的ListOperations操作Redis List列表。
版本:JDK 1.8,Spring Boot 2.6.3,redis-6.2.5
1.微服务中Redis配置信息
1.1在application.yml中Redis配置信息
spring:
redis:
host: 192.168.19.203
port: 28001
password: 12345678
timeout: 50000
1.2加载简要逻辑
Spring Boot微服务在启动时,自动注解机制会读取application.yml的注入到RedisProperties对象。在Spring环境中就能取到Redis相关配置信息了。
类全称:org.springframework.boot.autoconfigure.data.redis.RedisProperties
1.3在pom.xml添加依赖
org.springframework.boot
spring-boot-starter-data-redis
2.配置RedisTemplate
2.1配置RedisTemplate
@Configuration
public class RedisConfig {
@Bean("redisTemplate")
public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
// 1.创建RedisTemplate对象
RedisTemplate redisTemplate = new RedisTemplate();
// 2.加载Redis配置
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
// 3.配置key序列化
RedisSerializer> stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// 4.配置Value序列化
Jackson2JsonRedisSerializer
2.2解析
在配置RedisTemplate后,在Spring环境中,可以@Autowired自动注入方式注入操作Redis对象。比如:RedisTemplate、ListOperations。
3.使用ListOperations操作Redis List列表
3.1简要说明
使用ListOperationsRedis List列表,常用操作:增、查、删、设置超时等。
3.2操作示例
@RestController
@RequestMapping("/hub/example/load")
@Slf4j
public class LoadController {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ListOperations listOperations;
/**
* 操作List,使用ListOperations
* 对应写命令: LPUSH 队列名称 值
* 对应读命令: LPOP 队列名称
* 对应写命令: RPUSH 队列名称 值
* 对应读命令: RPOP 队列名称
*/
@GetMapping("/listOperations")
public Object loadData03() {
log.info("ListOperations操作开始...");
// 1.增
listOperations.leftPush("CityInfo:Hangzhou03", "杭州");
listOperations.rightPush("CityInfo:Hangzhou03", "苏州");
// 2.查,查出队列指定范围元素,不会删除队列里面数据,(0,-1)查出全部元素
listOperations.leftPush("CityInfo:Hangzhou03", "杭州");
listOperations.leftPush("CityInfo:Hangzhou03", "苏州");
List cityList = redisTemplate.boundListOps("CityInfo:Hangzhou03").range(0, -1);
cityList.forEach((value)->{
System.out.println("value="+value);
});
// 3.取,逐个取出队列元素(取出一个元素后,队列就没有这个元素了)
Object city01 = listOperations.leftPop("CityInfo:Hangzhou03");
Object city02 = listOperations.rightPop("CityInfo:Hangzhou03");
log.info("city01=" + city01 + ",city02=" + city02);
// 4.删
listOperations.leftPush("CityInfo:Hangzhou03", "杭州");
listOperations.leftPush("CityInfo:Hangzhou03", "苏州");
redisTemplate.delete("CityInfo:Hangzhou03");
// 5.设置超时
listOperations.leftPush("CityInfo:Hangzhou03", "上海");
redisTemplate.boundValueOps("CityInfo:Hangzhou03").expire(5, TimeUnit.MINUTES);
redisTemplate.expire("CityInfo:Hangzhou03", 10, TimeUnit.MINUTES);
// 6.查询List的元素个数
Long size =listOperations.size("CityInfo:Hangzhou03");
System.out.println("查询List的元素个数,size="+size);
log.info("ListOperations操作结束...");
return "执行成功";
}
}
3.3测试验证
使用Postman测试。
请求RUL:http://127.0.0.1:18205/hub-205-redis/hub/example/load/listOperations
4.ListOperations接口
4.1接口
ListOperations是一个接口,默认实现类是DefaultListOperations。
接口:org.springframework.data.redis.core.ListOperations。
实现类:org.springframework.data.redis.core.DefaultListOperations。
4.2接口源码
在源码中,查看接口具体方法,可以快速了解该接口具备功能,以便在生产中能根据实际场景对号入座找到合适方法解决实际问题。
public interface ListOperations {
@Nullable
List range(K key, long start, long end);
void trim(K key, long start, long end);
@Nullable
Long size(K key);
@Nullable
Long leftPush(K key, V value);
@Nullable
Long leftPushAll(K key, V... values);
@Nullable
Long leftPushAll(K key, Collection values);
@Nullable
Long leftPushIfPresent(K key, V value);
@Nullable
Long leftPush(K key, V pivot, V value);
@Nullable
Long rightPush(K key, V value);
@Nullable
Long rightPushAll(K key, V... values);
@Nullable
Long rightPushAll(K key, Collection values);
@Nullable
Long rightPushIfPresent(K key, V value);
@Nullable
Long rightPush(K key, V pivot, V value);
@Nullable
default V move(ListOperations.MoveFrom from, ListOperations.MoveTo to) {
Assert.notNull(from, "Move from must not be null");
Assert.notNull(to, "Move to must not be null");
return this.move(from.key, from.direction, to.key, to.direction);
}
@Nullable
V move(K sourceKey, Direction from, K destinationKey, Direction to);
@Nullable
default V move(ListOperations.MoveFrom from, ListOperations.MoveTo to, Duration timeout) {
Assert.notNull(from, "Move from must not be null");
Assert.notNull(to, "Move to must not be null");
Assert.notNull(timeout, "Timeout must not be null");
Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative");
return this.move(from.key, from.direction, to.key, to.direction, TimeoutUtils.toMillis(timeout.toMillis(), TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS);
}
@Nullable
default V move(K sourceKey, Direction from, K destinationKey, Direction to, Duration timeout) {
Assert.notNull(timeout, "Timeout must not be null");
Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative");
return this.move(sourceKey, from, destinationKey, to, TimeoutUtils.toMillis(timeout.toMillis(), TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS);
}
@Nullable
V move(K sourceKey, Direction from, K destinationKey, Direction to, long timeout, TimeUnit unit);
void set(K key, long index, V value);
@Nullable
Long remove(K key, long count, Object value);
@Nullable
V index(K key, long index);
Long indexOf(K key, V value);
Long lastIndexOf(K key, V value);
@Nullable
V leftPop(K key);
@Nullable
List leftPop(K key, long count);
@Nullable
V leftPop(K key, long timeout, TimeUnit unit);
@Nullable
default V leftPop(K key, Duration timeout) {
Assert.notNull(timeout, "Timeout must not be null");
Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative");
return this.leftPop(key, TimeoutUtils.toSeconds(timeout), TimeUnit.SECONDS);
}
@Nullable
V rightPop(K key);
@Nullable
List rightPop(K key, long count);
@Nullable
V rightPop(K key, long timeout, TimeUnit unit);
@Nullable
default V rightPop(K key, Duration timeout) {
Assert.notNull(timeout, "Timeout must not be null");
Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative");
return this.rightPop(key, TimeoutUtils.toSeconds(timeout), TimeUnit.SECONDS);
}
@Nullable
V rightPopAndLeftPush(K sourceKey, K destinationKey);
@Nullable
V rightPopAndLeftPush(K sourceKey, K destinationKey, long timeout, TimeUnit unit);
@Nullable
default V rightPopAndLeftPush(K sourceKey, K destinationKey, Duration timeout) {
Assert.notNull(timeout, "Timeout must not be null");
Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative");
return this.rightPopAndLeftPush(sourceKey, destinationKey, TimeoutUtils.toSeconds(timeout), TimeUnit.SECONDS);
}
RedisOperations getOperations();
public static class MoveTo {
final K key;
final Direction direction;
MoveTo(K key, Direction direction) {
this.key = key;
this.direction = direction;
}
public static ListOperations.MoveTo toHead(K key) {
return new ListOperations.MoveTo(key, Direction.first());
}
public static ListOperations.MoveTo toTail(K key) {
return new ListOperations.MoveTo(key, Direction.last());
}
}
public static class MoveFrom {
final K key;
final Direction direction;
MoveFrom(K key, Direction direction) {
this.key = key;
this.direction = direction;
}
public static ListOperations.MoveFrom fromHead(K key) {
return new ListOperations.MoveFrom(key, Direction.first());
}
public static ListOperations.MoveFrom fromTail(K key) {
return new ListOperations.MoveFrom(key, Direction.last());
}
}
}
以上,感谢。
2023年4月12日