From a6fa3721c7c91afacd1abb33e1373f1874e53074 Mon Sep 17 00:00:00 2001 From: Junsoo Choi Date: Wed, 21 Feb 2024 20:41:18 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20Redis=20=EB=94=94=ED=8E=9C=EB=8D=98?= =?UTF-8?q?=EC=8B=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index 23e302fd7..1e83a0521 100644 --- a/build.gradle +++ b/build.gradle @@ -37,6 +37,8 @@ dependencies { // swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' + // redis + implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' From 8c80735cdfea1d18534dc74181bd48b4e9bb1165 Mon Sep 17 00:00:00 2001 From: Junsoo Choi Date: Wed, 21 Feb 2024 20:47:33 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20yml=20=ED=99=98=EA=B2=BD=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index b5452bdbb..955e31afe 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -24,5 +24,10 @@ spring: hibernate: format_sql: true + redis: + data: + host: 127.0.0.1 + port: 6379 + logging.level: org.hibernate.SQL: debug From 4b2a2cc976ad12f7d01ffa2928cecb8ca368298e Mon Sep 17 00:00:00 2001 From: Junsoo Choi Date: Wed, 21 Feb 2024 23:32:30 +0900 Subject: [PATCH 3/7] =?UTF-8?q?refactor:=20yml=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 955e31afe..7d5dbd195 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -24,8 +24,8 @@ spring: hibernate: format_sql: true - redis: - data: + data: + redis: host: 127.0.0.1 port: 6379 From 9ee3732ddb6262024f64c9468a083af0f6f2aedb Mon Sep 17 00:00:00 2001 From: Junsoo Choi Date: Wed, 21 Feb 2024 23:32:42 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20config=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/RedisConfig.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/balancetalk/global/config/RedisConfig.java diff --git a/src/main/java/balancetalk/global/config/RedisConfig.java b/src/main/java/balancetalk/global/config/RedisConfig.java new file mode 100644 index 000000000..1e028999f --- /dev/null +++ b/src/main/java/balancetalk/global/config/RedisConfig.java @@ -0,0 +1,35 @@ +package balancetalk.global.config; + +import org.springframework.beans.factory.annotation.Value; +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.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +@EnableRedisRepositories +public class RedisConfig { + + @Value("${spring.data.redis.port}") + private int port; + + @Value("${spring.data.redis.host}") + private String host; + + @Bean + public RedisConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(host, port); + } + + @Bean + public RedisTemplate redisTemplate() { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new StringRedisSerializer()); + redisTemplate.setConnectionFactory(redisConnectionFactory()); + return redisTemplate; + } +} From 50b1d1555b4cfde20dd7781fd7556e583dd39a97 Mon Sep 17 00:00:00 2001 From: Junsoo Choi Date: Wed, 21 Feb 2024 23:32:55 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20service=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../redis/application/RedisService.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/main/java/balancetalk/global/redis/application/RedisService.java diff --git a/src/main/java/balancetalk/global/redis/application/RedisService.java b/src/main/java/balancetalk/global/redis/application/RedisService.java new file mode 100644 index 000000000..b102cf319 --- /dev/null +++ b/src/main/java/balancetalk/global/redis/application/RedisService.java @@ -0,0 +1,70 @@ +package balancetalk.global.redis.application; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Component +@RequiredArgsConstructor +public class RedisService { + + private final RedisTemplate redisTemplate; + + public void setValues(String key, String data) { + ValueOperations values = redisTemplate.opsForValue(); + values.set(key, data); + } + + /* + key와 data, 만료 시간을 Redis에 저장 + */ + public void setValues(String key, String data, Duration duration) { + ValueOperations values = redisTemplate.opsForValue(); + values.set(key, data, duration); + } + + @Transactional(readOnly = true) + public String getValues(String key) { + ValueOperations values = redisTemplate.opsForValue(); + if (values.get(key) == null) { + return "false"; + } + return (String) values.get(key); + } + + public void deleteValues(String key) { + redisTemplate.delete(key); + } + + public void expireValues(String key, int timeout) { + redisTemplate.expire(key, timeout, TimeUnit.MILLISECONDS); + } + + /* + 해당 키와 해시키가 존재하면, 해당 값을 가져오고 없을 경우엔 빈 문자열 반환 + */ + public String getHashOps(String key, String hashKey) { + HashOperations values = redisTemplate.opsForHash(); + boolean exists = Boolean.TRUE.equals(values.hasKey(key, hashKey)); + if (exists) { + return (String) redisTemplate.opsForHash().get(key, hashKey); + } + return ""; // 빈 문자열 반환 + } + + public void deleteHashOps(String key, String hashKey) { + HashOperations values = redisTemplate.opsForHash(); + values.delete(key, hashKey); + } + + public boolean checkExistsValue(String value) { + return !value.equals("false"); + } +} From 16897265d23fedfbb843e129826c7e19fd335c31 Mon Sep 17 00:00:00 2001 From: Junsoo Choi Date: Wed, 21 Feb 2024 23:33:12 +0900 Subject: [PATCH 6/7] =?UTF-8?q?fix:=20BalanceOption=20import=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/comment/application/CommentServiceTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/balancetalk/module/comment/application/CommentServiceTest.java b/src/test/java/balancetalk/module/comment/application/CommentServiceTest.java index fccff9b17..70b455699 100644 --- a/src/test/java/balancetalk/module/comment/application/CommentServiceTest.java +++ b/src/test/java/balancetalk/module/comment/application/CommentServiceTest.java @@ -17,6 +17,7 @@ import balancetalk.module.member.domain.Member; import balancetalk.module.member.domain.MemberRepository; +import balancetalk.module.post.domain.BalanceOption; import balancetalk.module.post.domain.Post; import balancetalk.module.post.domain.PostRepository; import balancetalk.module.vote.domain.Vote; From 0205665da2e5a141b0002915e11524ff4e20bf06 Mon Sep 17 00:00:00 2001 From: Junsoo Choi Date: Wed, 21 Feb 2024 23:33:23 +0900 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20Redis=20CRUD=20=EB=8B=A8=EC=9C=84=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../redis/application/RedisServiceTest.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/test/java/balancetalk/global/redis/application/RedisServiceTest.java diff --git a/src/test/java/balancetalk/global/redis/application/RedisServiceTest.java b/src/test/java/balancetalk/global/redis/application/RedisServiceTest.java new file mode 100644 index 000000000..82e2e86af --- /dev/null +++ b/src/test/java/balancetalk/global/redis/application/RedisServiceTest.java @@ -0,0 +1,77 @@ +package balancetalk.global.redis.application; + +import org.junit.jupiter.api.BeforeEach; +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 java.time.Duration; +import static org.assertj.core.api.Assertions.*; +import static org.awaitility.Awaitility.await; + +@SpringBootTest +class RedisCrudTEST { + + final String KEY = "key"; + final String VALUE = "value"; + final Duration DURATION = Duration.ofMillis(5000); + + @Autowired + private RedisService redisService; + + @BeforeEach + void setUp() { + redisService.setValues(KEY, VALUE, DURATION); + } + @Test + @DisplayName("Redis 데이터 저장후 조회 - 성공") + void Save_Find_Success() { + // when + String findValue = redisService.getValues(KEY); + + // then + assertThat(findValue).isEqualTo(VALUE); + } + + @Test + @DisplayName("Redis에 저장된 데이터 수정 - 성공") + void Update_Success() { + // given + String updatedValue = "updatedValue"; + redisService.setValues(KEY, updatedValue, DURATION); + + // when + String findValue = redisService.getValues(KEY); + + // then + assertThat(findValue).isEqualTo(updatedValue); + assertThat(findValue).isNotEqualTo(VALUE); + } + + @Test + @DisplayName("Redis에 저장된 데이터 삭제 - 성공") + void Delete_Success() { + // when + redisService.deleteValues(KEY); + + // then + assertThat(redisService.getValues(KEY)).isEqualTo("false"); + } + + @Test + @DisplayName("만료시간이 지간 데이터 삭제 - 성공") + void Expired_Success() { + // when + String findValue = redisService.getValues(KEY); + + // then + await().pollDelay(Duration.ofMillis(6000)).untilAsserted( + () -> { + String expiredValue = redisService.getValues(KEY); + assertThat(expiredValue).isNotEqualTo(findValue); + assertThat(expiredValue).isEqualTo("false"); + } + ); + } + +} \ No newline at end of file