From e35df883729474f0f2084ed96e4e36a32960ea9c Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Jul 2024 23:36:23 +0900 Subject: [PATCH 01/12] =?UTF-8?q?feat:=20LocalDate=EB=A5=BC=20json?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=ED=99=98=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20-=20#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index cbbca56..5d2591d 100644 --- a/build.gradle +++ b/build.gradle @@ -42,6 +42,9 @@ dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'//AWS implementation 'org.springframework.boot:spring-boot-starter-data-redis'//Redis + + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' //localDateTime json변환을 위함. + implementation 'com.fasterxml.jackson.core:jackson-databind' } tasks.named('test') { From 0ecb0b47b3f4fef8c69f84ae2bc4d50411455c36 Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Jul 2024 23:38:09 +0900 Subject: [PATCH 02/12] =?UTF-8?q?feat:=20cachemanager=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=20-#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../refreshrator/config/RedisConfig.java | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/hackathonteam1/refreshrator/config/RedisConfig.java b/src/main/java/com/hackathonteam1/refreshrator/config/RedisConfig.java index 4aced21..634ad80 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/config/RedisConfig.java +++ b/src/main/java/com/hackathonteam1/refreshrator/config/RedisConfig.java @@ -1,17 +1,21 @@ package com.hackathonteam1.refreshrator.config; import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.context.annotation.Primary; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; -import org.springframework.data.redis.core.RedisKeyValueAdapter; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; +import java.time.Duration; + @Configuration public class RedisConfig { @@ -25,8 +29,27 @@ public RedisConfig(@Value("${spring.data.redis.host}") String redisHost, } @Bean + public CacheManager redisCacheManager(){ + RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig() //Redis 캐시 설정을 정의하기 위한 클래스, 기본 캐시 구성 가져옴. + .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) //key를 String으로 직렬화 + .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())) //value를 json으로 직렬화 + .entryTtl(Duration.ofMinutes(15L)); //캐시에 15분 저장 + + return RedisCacheManager.RedisCacheManagerBuilder + .fromConnectionFactory(redisConnectionFactoryForDb1()) //redis db1로 연결 + .cacheDefaults(configuration) + .build(); + } + + @Bean + @Primary public RedisConnectionFactory redisConnectionFactory(){ - return new LettuceConnectionFactory(redisHost, redisPort); + return createLettuceConnectionFactory(0); + } + + @Bean + public RedisConnectionFactory redisConnectionFactoryForDb1(){ + return createLettuceConnectionFactory(1); } @Bean @@ -39,4 +62,10 @@ public RedisTemplate redisTemplate(RedisConnectionFactory redisConn redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); //Hash의 value를 json으로 시리얼라이즈 return redisTemplate; } -} + + private LettuceConnectionFactory createLettuceConnectionFactory(int database){ + LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisHost, redisPort); + lettuceConnectionFactory.setDatabase(database); + return lettuceConnectionFactory; + } +} \ No newline at end of file From 77585dc17674df5ab703285a2ad6fe13dd70d77d Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Jul 2024 23:38:28 +0900 Subject: [PATCH 03/12] =?UTF-8?q?feat:=20=EC=BA=90=EC=8B=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=9D=B8=EC=A7=80=EC=8B=9C=ED=82=A4=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=AA=85=EC=8B=9C=20-#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hackathonteam1/refreshrator/RefreshratorApplication.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/hackathonteam1/refreshrator/RefreshratorApplication.java b/src/main/java/com/hackathonteam1/refreshrator/RefreshratorApplication.java index 3ea5522..6b348d3 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/RefreshratorApplication.java +++ b/src/main/java/com/hackathonteam1/refreshrator/RefreshratorApplication.java @@ -2,10 +2,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication @EnableJpaAuditing +@EnableCaching public class RefreshratorApplication { public static void main(String[] args) { From 67d02434cad552511287fdd35eb93e40e3cff8cf Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Jul 2024 23:39:46 +0900 Subject: [PATCH 04/12] =?UTF-8?q?feat:=20json=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=ED=99=98=EC=9D=84=20=EC=9C=84=ED=95=B4=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=9E=91=EC=84=B1=20?= =?UTF-8?q?-#98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/fridge/AddFridgeDto.java | 2 ++ .../dto/request/recipe/ModifyRecipeDto.java | 1 + .../dto/response/PaginationDto.java | 2 ++ .../dto/response/file/ImageDto.java | 6 +++--- .../dto/response/fridge/FridgeItemDto.java | 15 +++++++++++++-- .../dto/response/fridge/FridgeItemListDto.java | 6 +++--- .../dto/response/ingredient/IngredientDto.java | 6 ++++-- .../response/ingredient/IngredientListDto.java | 6 +++--- .../dto/response/recipe/DetailRecipeDto.java | 17 ++++++++++++++--- .../recipe/IngredientRecipeResponseDto.java | 4 ++++ .../dto/response/recipe/RecipeDto.java | 17 +++++++++++++++++ .../dto/response/recipe/RecipeListDto.java | 6 +++--- 12 files changed, 69 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/request/fridge/AddFridgeDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/request/fridge/AddFridgeDto.java index 6a0370e..8c13b9e 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/request/fridge/AddFridgeDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/request/fridge/AddFridgeDto.java @@ -3,12 +3,14 @@ import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import java.time.LocalDate; import java.util.UUID; @Getter @AllArgsConstructor +@NoArgsConstructor public class AddFridgeDto { //재료 diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/request/recipe/ModifyRecipeDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/request/recipe/ModifyRecipeDto.java index a88b5d2..a44221a 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/request/recipe/ModifyRecipeDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/request/recipe/ModifyRecipeDto.java @@ -4,6 +4,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import java.util.UUID; diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/PaginationDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/PaginationDto.java index 87f0df1..f7b0cdb 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/PaginationDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/PaginationDto.java @@ -2,10 +2,12 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import org.springframework.data.domain.Page; @Getter @AllArgsConstructor +@NoArgsConstructor public class PaginationDto { private int currentPage; private int totalPage; diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/file/ImageDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/file/ImageDto.java index 51c0435..004d0e3 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/file/ImageDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/file/ImageDto.java @@ -1,15 +1,15 @@ package com.hackathonteam1.refreshrator.dto.response.file; import com.hackathonteam1.refreshrator.entity.Image; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; +import lombok.*; import java.util.UUID; @Getter @Builder @AllArgsConstructor +@Setter +@NoArgsConstructor public class ImageDto { private UUID id; diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/fridge/FridgeItemDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/fridge/FridgeItemDto.java index 1311655..b277013 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/fridge/FridgeItemDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/fridge/FridgeItemDto.java @@ -1,16 +1,27 @@ package com.hackathonteam1.refreshrator.dto.response.fridge; -import lombok.Builder; -import lombok.Getter; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; + +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import lombok.*; import java.time.LocalDate; import java.util.UUID; @Builder @Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor public class FridgeItemDto { private UUID id; private String ingredientName; private UUID ingredientId; + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") private LocalDate expirationDate; } diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/fridge/FridgeItemListDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/fridge/FridgeItemListDto.java index 409b151..5db3720 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/fridge/FridgeItemListDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/fridge/FridgeItemListDto.java @@ -1,14 +1,14 @@ package com.hackathonteam1.refreshrator.dto.response.fridge; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; +import lombok.*; import java.util.List; @Getter @Builder @AllArgsConstructor +@Setter +@NoArgsConstructor public class FridgeItemListDto { private List coldStorage; // 냉장 private List frozen; // 냉동 diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/ingredient/IngredientDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/ingredient/IngredientDto.java index f4c7a43..5df4038 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/ingredient/IngredientDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/ingredient/IngredientDto.java @@ -1,13 +1,15 @@ package com.hackathonteam1.refreshrator.dto.response.ingredient; import com.hackathonteam1.refreshrator.entity.Ingredient; -import lombok.Builder; -import lombok.Getter; +import lombok.*; import java.util.UUID; @Builder @Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor public class IngredientDto { private UUID id; diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/ingredient/IngredientListDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/ingredient/IngredientListDto.java index 6528848..d3551ce 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/ingredient/IngredientListDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/ingredient/IngredientListDto.java @@ -1,14 +1,14 @@ package com.hackathonteam1.refreshrator.dto.response.ingredient; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; +import lombok.*; import java.util.List; @Getter @Builder @AllArgsConstructor +@Setter +@NoArgsConstructor public class IngredientListDto { private List ingredients; } diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/DetailRecipeDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/DetailRecipeDto.java index c9119c9..54d52c4 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/DetailRecipeDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/DetailRecipeDto.java @@ -1,12 +1,15 @@ package com.hackathonteam1.refreshrator.dto.response.recipe; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.hackathonteam1.refreshrator.dto.response.file.ImageDto; import com.hackathonteam1.refreshrator.entity.Image; import com.hackathonteam1.refreshrator.entity.IngredientRecipe; import com.hackathonteam1.refreshrator.entity.Recipe; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; +import lombok.*; import java.time.LocalDateTime; import java.util.List; @@ -16,6 +19,8 @@ @Getter @Builder @AllArgsConstructor +@Setter +@NoArgsConstructor public class DetailRecipeDto { private UUID id; private String name; @@ -23,7 +28,13 @@ public class DetailRecipeDto { private String cookingStep; private int likeCount; private ImageDto image; + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss") private LocalDateTime createdAt; + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss") private LocalDateTime updatedAt; public static DetailRecipeDto mapping(Recipe recipe, List ingredientRecipes){ diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/IngredientRecipeResponseDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/IngredientRecipeResponseDto.java index 0597a1f..c765ab7 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/IngredientRecipeResponseDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/IngredientRecipeResponseDto.java @@ -5,11 +5,15 @@ import com.hackathonteam1.refreshrator.entity.IngredientRecipe; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import java.util.UUID; @Getter @AllArgsConstructor +@Setter +@NoArgsConstructor public class IngredientRecipeResponseDto { private UUID id; diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/RecipeDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/RecipeDto.java index 754f39e..264ed46 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/RecipeDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/RecipeDto.java @@ -1,22 +1,39 @@ package com.hackathonteam1.refreshrator.dto.response.recipe; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.hackathonteam1.refreshrator.dto.response.file.ImageDto; import com.hackathonteam1.refreshrator.entity.Recipe; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import java.time.LocalDateTime; import java.util.UUID; @Getter @AllArgsConstructor +@Setter +@NoArgsConstructor public class RecipeDto { private UUID recipeId; private String name; private int likeCount; private ImageDto image; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss") private LocalDateTime createdAt; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss") private LocalDateTime updatedAt; public static RecipeDto mapping(Recipe recipe){ return new RecipeDto(recipe.getId(), recipe.getName(), recipe.getLikeCount(), diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/RecipeListDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/RecipeListDto.java index 34b920f..8482167 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/RecipeListDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/RecipeListDto.java @@ -2,9 +2,7 @@ import com.hackathonteam1.refreshrator.dto.response.PaginationDto; import com.hackathonteam1.refreshrator.entity.Recipe; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; +import lombok.*; import org.springframework.data.domain.Page; import java.util.List; @@ -13,6 +11,8 @@ @Getter @AllArgsConstructor @Builder +@NoArgsConstructor +@Setter public class RecipeListDto { private List recipeList; private PaginationDto pagination; From 25d6fe71138535dd5b7bbe2b4aaa405c2736e63c Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Jul 2024 23:43:36 +0900 Subject: [PATCH 05/12] =?UTF-8?q?feat:=20=EC=BA=90=EC=8B=B1=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20-#98=20=EB=83=89=EC=9E=A5=EA=B3=A0=20=EC=9E=AC?= =?UTF-8?q?=EB=A3=8C=20=EC=A0=84=EC=B2=B4=20=EC=A1=B0=ED=9A=8C=EC=97=90=20?= =?UTF-8?q?=ED=95=9C=ED=95=98=EC=97=AC=20=EC=BA=90=EC=8B=B1.=20=EC=9E=AC?= =?UTF-8?q?=EB=A3=8C=EC=97=90=20=EB=8C=80=ED=95=9C=20cud=20=EC=8B=9C=20?= =?UTF-8?q?=EC=BA=90=EC=8B=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hackathonteam1/refreshrator/service/FridgeService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/hackathonteam1/refreshrator/service/FridgeService.java b/src/main/java/com/hackathonteam1/refreshrator/service/FridgeService.java index 4492264..9feb164 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/service/FridgeService.java +++ b/src/main/java/com/hackathonteam1/refreshrator/service/FridgeService.java @@ -15,6 +15,8 @@ import com.hackathonteam1.refreshrator.repository.FridgeRepository; import com.hackathonteam1.refreshrator.repository.IngredientRepository; import lombok.AllArgsConstructor; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.time.LocalDate; @@ -30,6 +32,7 @@ public class FridgeService { private FridgeRepository fridgeRepository; //냉장고에 재료 추가 + @CacheEvict(value = "userIngredientsCache", key = "#user.getId()", cacheManager = "redisCacheManager") public void addIngredientInFridge(AddFridgeDto addFridgeDto, User user){ //재료 찾기 @@ -53,6 +56,7 @@ public void addIngredientInFridge(AddFridgeDto addFridgeDto, User user){ } //냉장고에 재료 정보 수정 메서드 + @CacheEvict(value = "userIngredientsCache", key = "#user.getId()", cacheManager = "redisCacheManager") public void updateIngredientInFridge(UUID fridgeItemId, AddFridgeDto addFridgeDto, User user){ //수정할 재료 찾기 @@ -72,6 +76,7 @@ public void updateIngredientInFridge(UUID fridgeItemId, AddFridgeDto addFridgeDt } //냉장고에 재료 삭제 메서드 + @CacheEvict(value = "userIngredientsCache", key = "#user.getId()", cacheManager = "redisCacheManager") public void deleteIngredientInFridge(UUID fridgeItemId, User user){ //삭제할 재료 찾기 FridgeItem fridgeItem=findFridgeItem(fridgeItemId); @@ -84,6 +89,7 @@ public void deleteIngredientInFridge(UUID fridgeItemId, User user){ } // 냉장고에 모든 재료 조회 + @Cacheable(value = "userIngredientsCache",key = "#user.getId()", cacheManager = "redisCacheManager") public FridgeItemListDto getIngredientsInFridge(User user) { // 유저의 냉장고 찾기 Fridge fridge = findFridge(user); From 27bcb65a6896b503e3563c9f1b6148b5b9ed7b35 Mon Sep 17 00:00:00 2001 From: jher235 Date: Tue, 30 Jul 2024 23:46:10 +0900 Subject: [PATCH 06/12] =?UTF-8?q?feat:=20=EB=A0=88=EC=8B=9C=ED=94=BC=20?= =?UTF-8?q?=EC=BA=90=EC=8B=B1=20=EC=9E=91=EC=84=B1=20-#98=20=EB=A0=88?= =?UTF-8?q?=EC=8B=9C=ED=94=BC=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C,?= =?UTF-8?q?=20=EB=A0=88=EC=8B=9C=ED=94=BC=20=EC=83=81=EC=84=B8=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EC=97=90=20=EB=8C=80=ED=95=98=EC=97=AC=20=EC=BA=90?= =?UTF-8?q?=EC=8B=B1=20=EC=9E=91=EC=84=B1.=20=EB=A0=88=EC=8B=9C=ED=94=BC?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1,=20=EB=A0=88=EC=8B=9C=ED=94=BC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95(+=EC=9E=AC=EB=A3=8C=20=EC=88=98=EC=A0=95),?= =?UTF-8?q?=20=EB=A0=88=EC=8B=9C=ED=94=BC=20=EC=82=AD=EC=A0=9C,=20?= =?UTF-8?q?=EC=A2=8B=EC=95=84=EC=9A=94=20=EC=B6=94=EA=B0=80,=20=EC=A2=8B?= =?UTF-8?q?=EC=95=84=EC=9A=94=20=EC=82=AD=EC=A0=9C=20=EC=8B=9C=20=EC=BA=90?= =?UTF-8?q?=EC=8B=9C=20=EC=82=AD=EC=A0=9C=EB=90=A8.=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C,=20=EC=83=81=EC=84=B8=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EB=8A=94=20=EA=B0=81=EA=B0=81=20=EC=BA=90=EC=8B=9C?= =?UTF-8?q?=EA=B0=80=20=EC=82=AD=EC=A0=9C=EB=90=98=EB=8A=94=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=EC=97=90=EC=84=9C=20=EC=95=BD=EA=B0=84=EC=9D=98=20?= =?UTF-8?q?=EC=B0=A8=EC=9D=B4=EA=B0=80=20=EC=A1=B4=EC=9E=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/RecipeServiceImpl.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java b/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java index 9299a9d..8e171d5 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java +++ b/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java @@ -29,6 +29,10 @@ import com.hackathonteam1.refreshrator.util.S3Uploader; import lombok.RequiredArgsConstructor; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.annotation.Caching; import org.springframework.http.MediaType; import org.springframework.data.domain.Page; @@ -61,6 +65,7 @@ public class RecipeServiceImpl implements RecipeService{ private final RecipeLikeRepository recipeLikeRepository; @Override + @Cacheable(value = "recipeListCache",key = "#keyword + '-' + #type + '-' + #page + '-' + #size", cacheManager = "redisCacheManager") public RecipeListDto getList(String keyword, String type, int page, int size) { Sort sort; @@ -85,6 +90,7 @@ public RecipeListDto getList(String keyword, String type, int page, int size) { @Override @Transactional + @CacheEvict(value = "recipeListCache", allEntries = true, cacheManager = "redisCacheManager") public void register(RegisterRecipeDto registerRecipeDto, User user) { Image image = null; @@ -106,6 +112,7 @@ public void register(RegisterRecipeDto registerRecipeDto, User user) { //상세조회 @Override + @Cacheable(value = "recipeDetailCache", key = "#recipeId", cacheManager = "redisCacheManager") public DetailRecipeDto getDetail(UUID recipeId) { Recipe recipe = findRecipeByRecipeId(recipeId); List ingredientRecipes = findAllIngredientRecipeByRecipe(recipe); @@ -116,6 +123,12 @@ public DetailRecipeDto getDetail(UUID recipeId) { //레시피명, 조리법 수정 @Override + @Caching( + evict = { + @CacheEvict(value = "recipeListCache", allEntries = true, cacheManager = "redisCacheManager"), + @CacheEvict(value = "recipeDetailCache", key = "#recipeId", cacheManager = "redisCacheManager") + } + ) public void modifyContent(ModifyRecipeDto modifyRecipeDto, User user, UUID recipeId) { Recipe recipe = findRecipeByRecipeId(recipeId); checkAuth(recipe.getUser(), user); @@ -137,6 +150,12 @@ public void modifyContent(ModifyRecipeDto modifyRecipeDto, User user, UUID recip //레시피 삭제 @Override + @Caching( + evict = { + @CacheEvict(value = "recipeListCache", allEntries = true, cacheManager = "redisCacheManager"), + @CacheEvict(value = "recipeDetailCache", key = "#recipeId", cacheManager = "redisCacheManager") + } + ) public void delete(UUID recipeId, User user) { Recipe recipe = findRecipeByRecipeId(recipeId); checkAuth(recipe.getUser(), user); @@ -146,6 +165,7 @@ public void delete(UUID recipeId, User user) { //레시피 재료 등록 @Override @Transactional + @CacheEvict(value = "recipeDetailCache", key = "#recipeId", cacheManager = "redisCacheManager") public void registerIngredientRecipe(User user, UUID recipeId, RegisterIngredientRecipesDto registerIngredientRecipesDto) { Recipe recipe = findRecipeByRecipeId(recipeId); checkAuth(recipe.getUser(), user); @@ -168,6 +188,7 @@ public void registerIngredientRecipe(User user, UUID recipeId, RegisterIngredien } @Override + @CacheEvict(value = "recipeDetailCache", key = "#recipeId", cacheManager = "redisCacheManager") public void deleteIngredientRecipe(User user, UUID recipeId, DeleteIngredientRecipesDto deleteIngredientRecipesDto) { Recipe recipe = findRecipeByRecipeId(recipeId); checkAuth(recipe.getUser(),user); @@ -235,9 +256,15 @@ public ImageDto registerImage(MultipartFile file) { } @Override + @Caching( + evict = { + @CacheEvict(value = "recipeListCache", allEntries = true, cacheManager = "redisCacheManager"), + } + ) public void deleteImage(UUID imageId, User user) { Image image = findImageByImageId(imageId); Recipe recipe = image.getRecipe(); + UUID recipeId = recipe.getId(); if(!recipe.isContainingImage()){ throw new BadRequestException(ErrorCode.IMAGE_NOT_IN_RECIPE); @@ -291,6 +318,12 @@ private void registerRecipeIngredient(Ingredient ingredient, Recipe recipe){ // 레시피에 좋아요 추가 @Override + @Caching( + evict = { + @CacheEvict(value = "recipeListCache", allEntries = true, cacheManager = "redisCacheManager"), + @CacheEvict(value = "recipeDetailCache", key = "#recipeId", cacheManager = "redisCacheManager") + } + ) public void addLikeToRecipe(User user, UUID recipeId){ Recipe recipe = findRecipeByRecipeId(recipeId); @@ -305,6 +338,12 @@ public void addLikeToRecipe(User user, UUID recipeId){ // 레시피에 좋아요 삭제 @Override + @Caching( + evict = { + @CacheEvict(value = "recipeListCache", allEntries = true, cacheManager = "redisCacheManager"), + @CacheEvict(value = "recipeDetailCache", key = "#recipeId", cacheManager = "redisCacheManager") + } + ) public void deleteLikeFromRecipe(User user, UUID recipeId){ Recipe recipe = findRecipeByRecipeId(recipeId); // 해당 레시피에서 내가 누른 좋아요 반환 From 5b737116b3fbc81059d2cad1f0c0e1a92fbedc16 Mon Sep 17 00:00:00 2001 From: jher235 Date: Thu, 1 Aug 2024 00:46:55 +0900 Subject: [PATCH 07/12] =?UTF-8?q?feat:=20=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=20=EC=8B=A4=ED=96=89=20=EC=8B=9C=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EC=A0=95=EC=9D=98=20=EB=84=A4=ED=8A=B8=EC=9B=8C?= =?UTF-8?q?=ED=81=AC=EC=97=90=20=EC=BB=A8=ED=85=8C=EC=9D=B4=EB=84=88?= =?UTF-8?q?=EB=A5=BC=20=EC=97=B0=EA=B2=B0=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20-=20#100?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/gradle.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index d5a2c42..9a909b6 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -63,6 +63,6 @@ jobs: # 실행할 작업들에 대한 설정 sudo docker pull ${{secrets.DOCKERHUB_USERNAME}}/${{secrets.DOCKERHUB_IMAGE}} sudo docker ps -q | xargs -r sudo docker stop sudo docker ps -aq | xargs -r sudo docker rm - sudo docker run --name redis --rm -d -p 6379:6379 redis - sudo docker run --name ${{secrets.DOCKERHUB_IMAGE}} --rm -d -p 8080:8080 ${{secrets.DOCKERHUB_USERNAME}}/${{secrets.DOCKERHUB_IMAGE}} + sudo docker run --name redis --rm -d -p 6379:6379 --net my-network redis + sudo docker run --name ${{secrets.DOCKERHUB_IMAGE}} --rm -d --net my-network -p 8080:8080 ${{secrets.DOCKERHUB_USERNAME}}/${{secrets.DOCKERHUB_IMAGE}} sudo docker system prune -f \ No newline at end of file From 2106325f9b4951a6053fb712ea4b291c9555b778 Mon Sep 17 00:00:00 2001 From: jher235 Date: Sat, 3 Aug 2024 21:57:23 +0900 Subject: [PATCH 08/12] =?UTF-8?q?feat:=20=EB=A0=88=EC=8B=9C=ED=94=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=EB=A5=BC=20=EC=B0=BE?= =?UTF-8?q?=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?-=20#102?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../refreshrator/repository/ImageRepository.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/hackathonteam1/refreshrator/repository/ImageRepository.java b/src/main/java/com/hackathonteam1/refreshrator/repository/ImageRepository.java index 6fbef8e..01b109a 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/repository/ImageRepository.java +++ b/src/main/java/com/hackathonteam1/refreshrator/repository/ImageRepository.java @@ -1,9 +1,12 @@ package com.hackathonteam1.refreshrator.repository; import com.hackathonteam1.refreshrator.entity.Image; +import com.hackathonteam1.refreshrator.entity.Recipe; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; import java.util.UUID; public interface ImageRepository extends JpaRepository { + Optional findByRecipe(Recipe recipe); } From 89dd8857aedd2626ac22dab69e3ccedd3a1f75ea Mon Sep 17 00:00:00 2001 From: jher235 Date: Sat, 3 Aug 2024 21:58:08 +0900 Subject: [PATCH 09/12] =?UTF-8?q?refactor:=20=EB=A0=88=EC=8B=9C=ED=94=BC?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=20=EC=8B=9C=20s3=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=A0=88=EC=8B=9C=ED=94=BC=EC=9D=98=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=82=AD=EC=A0=9C=20-=20#102?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../refreshrator/service/RecipeServiceImpl.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java b/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java index 9299a9d..c15f7dd 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java +++ b/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java @@ -42,10 +42,7 @@ import java.io.IOException; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; @Service @@ -140,6 +137,10 @@ public void modifyContent(ModifyRecipeDto modifyRecipeDto, User user, UUID recip public void delete(UUID recipeId, User user) { Recipe recipe = findRecipeByRecipeId(recipeId); checkAuth(recipe.getUser(), user); + if(recipe.isContainingImage()){ + Image image = findImageByRecipe(recipe); + s3Uploader.removeS3File(image.getUrl().split("/")[3]); + } recipeRepository.delete(recipe); } @@ -358,4 +359,8 @@ private void checkValidPage(Page pages, int page){ throw new NotFoundException(ErrorCode.PAGE_NOT_FOUND); } } + + private Image findImageByRecipe(Recipe recipe){ + return imageRepository.findByRecipe(recipe).orElseThrow(()->new NotFoundException(ErrorCode.IMAGE_NOT_FOUND)); + } } From f2ad85e3c9c1fc42e52355e9888475418fce6faa Mon Sep 17 00:00:00 2001 From: jher235 Date: Sun, 4 Aug 2024 22:48:43 +0900 Subject: [PATCH 10/12] =?UTF-8?q?feat:=20=EC=9E=91=EC=84=B1=EC=9E=90=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80=20-#104?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../refreshrator/dto/response/recipe/DetailRecipeDto.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/DetailRecipeDto.java b/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/DetailRecipeDto.java index c9119c9..cfcccd0 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/DetailRecipeDto.java +++ b/src/main/java/com/hackathonteam1/refreshrator/dto/response/recipe/DetailRecipeDto.java @@ -19,6 +19,7 @@ public class DetailRecipeDto { private UUID id; private String name; + private String writer; private List ingredientRecipes; private String cookingStep; private int likeCount; @@ -29,7 +30,7 @@ public class DetailRecipeDto { public static DetailRecipeDto mapping(Recipe recipe, List ingredientRecipes){ List ingredientDtos = ingredientRecipes.stream().map( i->IngredientRecipeResponseDto.changeToDto(i)).collect(Collectors.toList()); - return new DetailRecipeDto(recipe.getId(), recipe.getName(), ingredientDtos, + return new DetailRecipeDto(recipe.getId(), recipe.getName(), recipe.getUser().getName(), ingredientDtos, recipe.getCookingStep(), recipe.getLikeCount(), ImageDto.mapping(recipe.getImage()), recipe.getCreatedAt(), recipe.getUpdatedAt()); } From 8df400327893dbd8716c8b7fb09dfa5c16aaccee Mon Sep 17 00:00:00 2001 From: jher235 Date: Sun, 4 Aug 2024 22:49:11 +0900 Subject: [PATCH 11/12] =?UTF-8?q?refactor:=20=EC=A1=B0=EB=A6=AC=EB=B2=95?= =?UTF-8?q?=20=ED=95=84=EB=93=9C=205000=EC=9E=90=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20-=20#104?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/hackathonteam1/refreshrator/entity/Recipe.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/hackathonteam1/refreshrator/entity/Recipe.java b/src/main/java/com/hackathonteam1/refreshrator/entity/Recipe.java index 30c7f5c..e998126 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/entity/Recipe.java +++ b/src/main/java/com/hackathonteam1/refreshrator/entity/Recipe.java @@ -20,8 +20,7 @@ public class Recipe extends BaseEntity{ @Column(nullable = false) private String name; - @Column(nullable = false) - @Lob + @Column(nullable = false, length = 5000) private String cookingStep; @ManyToOne(fetch = FetchType.LAZY, optional = false) From 2d39a9cc1b8bbbe801ee05a9169ce7eddf859f32 Mon Sep 17 00:00:00 2001 From: jher235 Date: Sun, 4 Aug 2024 22:50:31 +0900 Subject: [PATCH 12/12] =?UTF-8?q?refactor:=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=ED=99=95=EC=9E=A5=EC=9E=90=20=EC=B6=94=EA=B0=80=20-=20#104=20j?= =?UTF-8?q?pg,=20jpeg,=20gif,=20png=20->=20jpg,=20jpeg,=20png,=20gif,=20we?= =?UTF-8?q?bp,=20bmp,=20tiff,=20svg,=20heic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/RecipeServiceImpl.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java b/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java index 9299a9d..836a7f9 100644 --- a/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java +++ b/src/main/java/com/hackathonteam1/refreshrator/service/RecipeServiceImpl.java @@ -42,10 +42,7 @@ import java.io.IOException; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; @Service @@ -60,6 +57,8 @@ public class RecipeServiceImpl implements RecipeService{ private final ImageRepository imageRepository; private final RecipeLikeRepository recipeLikeRepository; + private static final List IMAGE_EXTENSION = Arrays.asList(".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".tiff", ".svg", ".heic"); + @Override public RecipeListDto getList(String keyword, String type, int page, int size) { @@ -92,6 +91,12 @@ public void register(RegisterRecipeDto registerRecipeDto, User user) { image = findImageByImageId(registerRecipeDto.getImageId()); } + //동일한 재료를 요청할 경우 예외처리 + Set ingredientIdSet = new HashSet<>(registerRecipeDto.getIngredientIds()); + if(ingredientIdSet.size() != registerRecipeDto.getIngredientIds().size()){ + throw new BadRequestException(ErrorCode.DUPLICATED_RECIPE_INGREDIENT); + } + Recipe recipe = Recipe.builder() .name(registerRecipeDto.getName()) .cookingStep(registerRecipeDto.getCookingStep()) @@ -101,7 +106,7 @@ public void register(RegisterRecipeDto registerRecipeDto, User user) { recipeRepository.save(recipe); - registerRecipeDto.getIngredientIds().stream().forEach(i -> registerRecipeIngredient(findIngredientByIngredientId(i),recipe)); + ingredientIdSet.stream().forEach(i -> registerRecipeIngredient(findIngredientByIngredientId(i),recipe)); } //상세조회 @@ -212,11 +217,10 @@ public RecipeListDto getRecommendation(int page, int size, int match, String typ @Override public ImageDto registerImage(MultipartFile file) { - if(!file.getContentType().equals(MediaType.IMAGE_GIF_VALUE) && - !file.getContentType().equals(MediaType.IMAGE_PNG_VALUE) && - !file.getContentType().equals(MediaType.IMAGE_JPEG_VALUE) ){ + String fileName = file.getOriginalFilename(); + if(!IMAGE_EXTENSION.stream().anyMatch(i-> fileName.endsWith(i))){ throw new FileStorageException(ErrorCode.FILE_TYPE_ERROR); - } + }; String url; try {