-
[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.javapackage 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 프로젝트를 참조하세요.
반응형'Spring Boot > 기타' 카테고리의 다른 글
[Spring Boot] Spring Boot 2.x에서 Spring Boot 3.x으로 버전 변경 (1) 2023.09.06 [Spring Boot] RedisJSON 연동 (0) 2023.07.17 [Spring Boot] ActiveMQ Queue, Topic 연동 (0) 2023.07.02 [Spring Boot] STOMP 사용 시 Interceptor 및 errorHandling 적용 (0) 2023.06.24 [Spring Boot] ActiveMQ + STOMP 연동 (0) 2023.06.17