ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Boot] RedisTemplate을 이용한 Redis Data Type 확인
    Spring Boot/기타 2023. 7. 2. 18:32
    반응형

    Redis Data Types

    • Strings : 단순한 텍스트나 이진 데이터를 저장하는데 사용되며, 각 키에 대해 하나의 값만 저장할 수 있습니다. Strings는 캐싱, 세션 관리, 카운팅 등에 사용됩니다.
    • Lists : 순서가 있는 문자열의 목록을 저장하는데 사용되며, 한 키에 여러 값을 저장할 수 있으며, 값들은 순서대로 저장됩니다. Lists는 대기열, 로그, 최근 작업 목록 등에 사용됩니다.
    • Sets : 중복되지 않는 값을 저장하는데 사용되며, 멤버 간의 순서가 없으며, 각 멤버는 유일합니다. Sets는 태그 처리, 중복 제거 등에 유용합니다.
    • Hashes : 필드-값 쌍을 저장하는 데 사용되며, 각 키에 대해 여러 개의 필드와 해당 필드에 연결된 값들을 저장할 수 있습니다. Hashes는 필드의 추가, 제거, 조회, 업데이트 등의 작업을 지원하며, 객체를 표현하고 저장하기에 유용합니다.
    • Sorted Sets : Sets과 유사하지만 각 멤버에 대한 순서가 있으며, 멤버는 "스코어"라는 값과 함께 저장되며, 이를 기준으로 정렬됩니다. Sorted Sets은 랭킹, 우선 순위 큐 등에 유용합니다.

    Redis Data Types : https://redis.io/docs/data-types

     

     

    1. Docker를 사용하여 Redis 설치

    Docker를 사용하여 Redis를 로컬에 설치하세요.

    docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest

    포트 6379는 Redis 연결, 포트 8001는 RedisInsight에 사용됩니다.

    Docker Hub : https://hub.docker.com/r/redis/redis-stack

     

    RedisInsight

    RedisInsight : https://developer.redis.com/explore/redisinsightv2/getting-started/

     

    2. 의존성 추가 

    RedisTemplate을 이용하기 위해 'spring-boot-starter-data-redis'를 추가하세요.

    build.gradle

    plugins {
        id 'java'
        id 'org.springframework.boot' version '3.1.1'
        id 'io.spring.dependency-management' version '1.1.0'
    }
    
    group = 'com.example'
    version = '0.0.1-SNAPSHOT'
    
    java {
        sourceCompatibility = '17'
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
    
        // SpringBoot
        implementation 'org.springframework.boot:spring-boot-starter-web'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    
        // Redis
        implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    
        // Lombok
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
        testCompileOnly 'org.projectlombok:lombok'
        testAnnotationProcessor 'org.projectlombok:lombok'
    }
    
    tasks.named('test') {
        useJUnitPlatform()
    }

    Maven Repository : https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis

     

    3. RedisConfig 설정

    Redis 데이터베이스와의 연결 설정 및 Redis 데이터 액세스를 위한 RedisTemplate을 이용하기 위해 설정을 추가하세요.

    RedisConfig.java

    package com.example.redis.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    @Configuration
    public class RedisConfig {
    
      /**
       * LettuceConnectionFactory를 사용하여 RedisConnectionFactory 빈을 생성하여 반환
       *
       * @return RedisConnectionFactory 객체
       */
      @Bean
      public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(new RedisStandaloneConfiguration());
      }
    
      /**
       * RedisTemplate 빈을 생성하여 반환
       *
       * @return RedisTemplate 객체
       */
      @Bean
      public RedisTemplate<?, ?> redisTemplate() {
        RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        return redisTemplate;
      }
    }

     

    4. RedisTemplate을 이용한 Redis Data Types 확인

    Redis에서 Data Type을 테스트하기 위해 RedisTemplate에 다음 메서드를 이용하여 구현하세요.

    • opsForValue() : Redis에서 문자열 값을 다루기 위한 ValueOperations 객체를 반환하며, 문자열 값을 설정하거나 가져오는 등의 연산을 수행할 수 있습니다.
    • opsForList() : Redis에서 리스트 값을 다루기 위한 ListOperations 객체를 반환하며, 리스트에 값을 추가하거나 가져오는 등의 연산을 수행할 수 있습니다.
    • opsForSet() : Redis에서 집합 값을 다루기 위한 SetOperations 객체를 반환하며, 집합에 값을 추가하거나 가져오는 등의 연산을 수행할 수 있습니다.
    • opsForHash() : Redis에서 해시 값을 다루기 위한 HashOperations 객체를 반환하며, 해시에 필드와 값을 추가하거나 가져오는 등의 연산을 수행할 수 있습니다.
    • opsForZSet() : Redis에서 정렬된 집합 값을 다루기 위한 ZSetOperations 객체를 반환하며, 정렬된 집합에 값을 추가하거나 가져오는 등의 연산을 수행할 수 있습니다.

    RedisTemplate : https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/core/RedisTemplate.html


    RedisTemplateTest.java

    package com.example.redis.config;
    
    import static org.junit.jupiter.api.Assertions.assertAll;
    import static org.junit.jupiter.api.Assertions.assertEquals;
    import static org.junit.jupiter.api.Assertions.assertFalse;
    import static org.junit.jupiter.api.Assertions.assertTrue;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    import lombok.extern.slf4j.Slf4j;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.redis.core.HashOperations;
    import org.springframework.data.redis.core.ListOperations;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.SetOperations;
    import org.springframework.data.redis.core.ValueOperations;
    import org.springframework.data.redis.core.ZSetOperations;
    import org.springframework.util.ObjectUtils;
    
    @Slf4j
    @SpringBootTest
    class RedisTemplateTest {
    
      @Autowired
      RedisTemplate redisTemplate;
    
      @DisplayName("Data Type이 String인 경우 테스트")
      @Test
      public void testString() {
    
        // Given
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        String requestKey = "string_key";
        String requestValue = "value_01";
    
        // When
        valueOperations.set(requestKey, requestValue, 5, TimeUnit.MINUTES);
    
        // Then
        String value = valueOperations.get(requestKey);
        log.info("testString - value: {}", value);
        assertEquals(value, value);
      }
    
      @DisplayName("Data Type이 List인 경우 테스트")
      @Test
      public void testList() {
    
        // Given
        ListOperations<String, String> listOperations = redisTemplate.opsForList();
        String key = "list_key";
        List<String> strs = Arrays.asList("value_01", "value_02", "value_03");
    
        // When
        for (String str : strs) {
          listOperations.leftPush(key, str);
        }
        redisTemplate.expire(key, 5, TimeUnit.MINUTES);
    
        // Then
        for (String str : strs) {
          String value = listOperations.rightPop(key);
          log.info("testList - value: {}", value);
          assertTrue(value.contains(str));
        }
      }
    
      @DisplayName("Data Type이 Set인 경우 테스트")
      @Test
      void testSet() {
    
        // Given
        SetOperations<String, String> setOperations = redisTemplate.opsForSet();
        String key = "set_key";
        String value01 = "value_01";
        String value02 = "value_02";
        String value03 = "value_03";
    
        // When
        setOperations.add(key, value01, value02, value03);
        redisTemplate.expire(key, 5, TimeUnit.MINUTES);
    
        // Then
        Set<String> members = setOperations.members(key);
        log.info("testSet - members: {}", members);
        assertFalse(ObjectUtils.isEmpty(members));
        assertAll(
            () -> assertTrue(members.contains(value01)),
            () -> assertTrue(members.contains(value02)),
            () -> assertTrue(members.contains(value03))
        );
      }
    
      @DisplayName("Data Type이 Hash인 경우 테스트")
      @Test
      void testHash() {
    
        // Given
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        String key = "hash_key";
        String hashKey = "field_01";
        String value = "value_01";
    
        // When
        hashOperations.put(key, hashKey, value);
        redisTemplate.expire(key, 5, TimeUnit.MINUTES);
    
        // Then
        Map<Object, Object> map = hashOperations.entries(key);
        log.info("testHash - map: {}", map);
        assertAll(
            () -> assertTrue(map.keySet().contains(hashKey)),
            () -> assertTrue(map.values().contains(value))
        );
      }
    
      @DisplayName("Data Type이 ZSet인 경우 테스트")
      @Test
      void testSortedSet() {
    
        // Given
        ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
        String key = "z_set_key";
        String value01 = "value_01";
        String value02 = "value_02";
        String value03 = "value_03";
    
        // When
        zSetOperations.add(key, value01, 1.0);
        zSetOperations.add(key, value02, 2.0);
        zSetOperations.add(key, value03, 3.0);
        redisTemplate.expire(key, 5, TimeUnit.MINUTES);
    
        // Then
        Set<String> range = zSetOperations.range(key, 0, 3);
        log.info("testSortedSet - range: {}", range);
        assertFalse(ObjectUtils.isEmpty(range));
        assertAll(
            () -> assertTrue(range.contains(value01)),
            () -> assertTrue(range.contains(value02)),
            () -> assertTrue(range.contains(value03))
        );
      }
    }

     

    소스 코드는 Github Repository - https://github.com/tychejin1218/redis 에서 redis-sample-01 프로젝트를 참조하세요.

    반응형

    댓글

Designed by Tistory.