ListOperations を使用して、Spring Boot マイクロサービスで Redis リスト リストを操作する

記録: 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 日

おすすめ

転載: blog.csdn.net/zhangbeizhen18/article/details/130119502