{"id":8787,"date":"2024-03-23T21:12:41","date_gmt":"2024-03-23T12:12:41","guid":{"rendered":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=8787"},"modified":"2024-03-24T14:53:11","modified_gmt":"2024-03-24T05:53:11","slug":"spring-boot-3-x-redis","status":"publish","type":"post","link":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=8787","title":{"rendered":"Spring Boot 3.x &#8211; Redis"},"content":{"rendered":"<h1>Spring Boot 3.x &#8211; Redis<\/h1>\n<p>Spring Boot 3.x \uc5d0\uc11c Redis \ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud569\ub2c8\ub2e4.<br \/>\nSpring Boot 3.x \uac00 JDK 17 \ubd80\ud130 \uc9c0\uc6d0\ud558\uc9c0\ub9cc \uc57d\uac04\uc758 \uc18c\uc2a4 \uc218\uc815\uc73c\ub85c \uc544\ub798 \ubc84\uc804\uc5d0\uc11c\ub3c4 \uc0ac\uc6a9 \uac00\ub2a5\ud560 \uac83\uc73c\ub85c \uc0dd\uac01\ud569\ub2c8\ub2e4.<\/p>\n<p>Spring Boot 2.7.14 \uc5d0\uc11c\ub3c4 \uc18c\uc2a4\ucf54\ub4dc \uc218\uc815\uc5c6\uc774 \uc815\uc0c1\uc791\ub3d9\ud569\ub2c8\ub2e4.<\/p>\n<h2>\uc758\uc874\uc131 \ucd94\uac00<\/h2>\n<pre><code class=\"language-groovy\">dependencies {\n    \/\/ redis\n    implementation &#039;org.springframework.boot:spring-boot-starter-data-redis&#039;\n    implementation &#039;org.springframework.data:spring-data-redis&#039;\n}<\/code><\/pre>\n<pre><code class=\"language-yaml\">spring:\n  data:\n    redis:\n      cluster:\n        nodes: 127.0.0.1:6379<\/code><\/pre>\n<h2>RedisConfig<\/h2>\n<p>Entity \ub97c String \uc73c\ub85c \ubcc0\ud658\ud574\uc11c \uc800\uc7a5\ud558\ub294\uac8c \uac00\uc7a5 \uac04\ud3b8\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">@Configuration\n@RequiredArgsConstructor\n@EnableRedisRepositories\npublic class RedisConfig {\n    private final RedisProperties redisProperties;\n\n    @Bean\n    public RedisConnectionFactory redisConnectionFactory() {\n        return new LettuceConnectionFactory(redisProperties.getHost(), redisProperties.getPort());\n    }\n\n    @Bean\n    public RedisTemplate&lt;?, ?&gt; redisTemplate() {\n        RedisTemplate&lt;?, ?&gt; redisTemplate = new RedisTemplate&lt;&gt;();\n        redisTemplate.setConnectionFactory(redisConnectionFactory());\n        redisTemplate.setEnableTransactionSupport(true);\n\n        redisTemplate.setKeySerializer(new StringRedisSerializer());\n        redisTemplate.setValueSerializer(new StringRedisSerializer());\n\n        redisTemplate.setHashKeySerializer(new StringRedisSerializer());\n        redisTemplate.setHashValueSerializer(new StringRedisSerializer());\n\n        return redisTemplate;\n    }\n}<\/code><\/pre>\n<h2>RedisService<\/h2>\n<p>ObjectMapper \ub97c \uc774\uc6a9\ud574 Json String &lt;-&gt; Entity \uac04 \ubcc0\ud658\uc744 \uc218\ud589\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">@Service\n@RequiredArgsConstructor\npublic class RedisService {\n    private final RedisTemplate&lt;String, Object&gt; redisTemplate;\n    private final ObjectMapper mapper;\n\n    public void putData(String key, Object value, Long expiredTime) {\n        try {\n            String jsonString = mapper.writeValueAsString(value);\n            redisTemplate.opsForValue().set(key, jsonString, expiredTime, TimeUnit.MILLISECONDS);\n        } catch (JsonProcessingException e) {\n            throw new RuntimeException(&quot;Invalid json format: &quot;, e);\n        }\n    }\n\n    public &lt;T&gt; Optional&lt;T&gt; getData(String key, Class&lt;T&gt; valueType) {\n        try {\n            String jsonString = (String) redisTemplate.opsForValue().get(key);\n            if (StringUtils.hasText(jsonString)) {\n                return Optional.ofNullable(mapper.readValue(jsonString, valueType));\n            }\n            return Optional.empty();\n        } catch (JsonProcessingException e) {\n            throw new RuntimeException(&quot;Invalid json format: &quot;, e);\n        }\n    }\n\n    public void remove(String key) {\n        redisTemplate.delete(key);\n    }\n}<\/code><\/pre>\n<h2>RestController<\/h2>\n<pre><code class=\"language-java\">@Getter\n@Setter\n@Builder\n@NoArgsConstructor\n@AllArgsConstructor\npublic class MyUserDto {\n    private String username;\n    private String password;\n    private String nickname;\n}<\/code><\/pre>\n<pre><code class=\"language-java\">@RestController\n@RequestMapping(&quot;\/&quot;)\n@RequiredArgsConstructor\npublic class MyController {\n    private final RedisService redisService;\n\n    @GetMapping(&quot;\/test&quot;)\n    public ResponseEntity&lt;?&gt; test() {\n        MyUserDto dto = MyUserDto\n                .builder()\n                .username(&quot;skyer9&quot;)\n                .nickname(&quot;\uc0c1\uad6c\ub9ac&quot;)\n                .build();\n        redisService.putData(&quot;my&quot;, dto, 1000L);\n        Optional&lt;MyUserDto&gt; saved = redisService.getData(&quot;my&quot;, MyUserDto.class);\n        return ResponseEntity.ok(saved);\n    }\n}<\/code><\/pre>\n<h2>\ud14c\uc2a4\ud2b8<\/h2>\n<p>\ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c <a href=\"http:\/\/localhost:8080\/test\">http:\/\/localhost:8080\/test<\/a> \ub85c \uc811\uc18d\ud558\uba74 \uc544\ub798 \ub0b4\uc6a9\uc774 \ud45c\uc2dc\ub429\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-json\">{&quot;username&quot;:&quot;skyer9&quot;,&quot;password&quot;:null,&quot;nickname&quot;:&quot;\uc0c1\uad6c\ub9ac&quot;}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Spring Boot 3.x &#8211; Redis Spring Boot 3.x \uc5d0\uc11c Redis \ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud569\ub2c8\ub2e4. Spring Boot 3.x \uac00 JDK 17 \ubd80\ud130 \uc9c0\uc6d0\ud558\uc9c0\ub9cc \uc57d\uac04\uc758 \uc18c\uc2a4 \uc218\uc815\uc73c\ub85c \uc544\ub798 \ubc84\uc804\uc5d0\uc11c\ub3c4 \uc0ac\uc6a9 \uac00\ub2a5\ud560 \uac83\uc73c\ub85c \uc0dd\uac01\ud569\ub2c8\ub2e4. Spring Boot 2.7.14 \uc5d0\uc11c\ub3c4 \uc18c\uc2a4\ucf54\ub4dc \uc218\uc815\uc5c6\uc774 \uc815\uc0c1\uc791\ub3d9\ud569\ub2c8\ub2e4. \uc758\uc874\uc131 \ucd94\uac00 dependencies { \/\/ redis implementation &#039;org.springframework.boot:spring-boot-starter-data-redis&#039; implementation &#039;org.springframework.data:spring-data-redis&#039; } spring: data: redis: cluster: nodes: 127.0.0.1:6379\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=8787\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,1],"tags":[],"class_list":["post-8787","post","type-post","status-publish","format-standard","hentry","category-spring-boot","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/8787","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=8787"}],"version-history":[{"count":4,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/8787\/revisions"}],"predecessor-version":[{"id":8842,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/8787\/revisions\/8842"}],"wp:attachment":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=8787"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=8787"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=8787"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}