記録: 402
シナリオ: RedisTemplate の ListOperations を使用して、Spring Boot マイクロサービスで Redis リスト リストを操作します。
バージョン: 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 に依存関係を追加する
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.RedisTemplate を構成する
2.1 RedisTemplate の設定
@Configuration
public class RedisConfig {
@Bean("redisTemplate")
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
// 1.创建RedisTemplate对象
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
// 2.加载Redis配置
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
// 3.配置key序列化
RedisSerializer<?> stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// 4.配置Value序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper objMapper = new ObjectMapper();
objMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objMapper.activateDefaultTyping(objMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objMapper);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
// 5.初始化RedisTemplate
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
}
2.2 分析
RedisTemplate を設定した後、Spring 環境で @Autowired 自動注入メソッドを使用して、Redis オブジェクトを注入および操作できます。例: RedisTemplate、ListOperations。
3. ListOperations を使用して Redis リスト リストを操作する
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<K, V> {
@Nullable
List<V> 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<V> 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<V> values);
@Nullable
Long rightPushIfPresent(K key, V value);
@Nullable
Long rightPush(K key, V pivot, V value);
@Nullable
default V move(ListOperations.MoveFrom<K> from, ListOperations.MoveTo<K> 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<K> from, ListOperations.MoveTo<K> 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<V> 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<V> 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<K, V> getOperations();
public static class MoveTo<K> {
final K key;
final Direction direction;
MoveTo(K key, Direction direction) {
this.key = key;
this.direction = direction;
}
public static <K> ListOperations.MoveTo<K> toHead(K key) {
return new ListOperations.MoveTo(key, Direction.first());
}
public static <K> ListOperations.MoveTo<K> toTail(K key) {
return new ListOperations.MoveTo(key, Direction.last());
}
}
public static class MoveFrom<K> {
final K key;
final Direction direction;
MoveFrom(K key, Direction direction) {
this.key = key;
this.direction = direction;
}
public static <K> ListOperations.MoveFrom<K> fromHead(K key) {
return new ListOperations.MoveFrom(key, Direction.first());
}
public static <K> ListOperations.MoveFrom<K> fromTail(K key) {
return new ListOperations.MoveFrom(key, Direction.last());
}
}
}
以上、ありがとう。
2023 年 4 月 12 日