Skip to content

Commit

Permalink
Merge pull request #123 from Alpha-Damyo/feature/#118-cache-area-data
Browse files Browse the repository at this point in the history
Feature/#118 Redis를 활용한 흡연구역 / 사진 정보 캐싱 + #120 리뷰 별점이 흡연구역 별점에 반영 안되는 버그 수정
  • Loading branch information
wjdwlghks authored Aug 20, 2024
2 parents 3c28496 + a84f67e commit ad66ae2
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 10 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ dependencies {

implementation 'org.springframework.boot:spring-boot-starter-validation'

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'

// jwt
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/damyo/alpha/AlphaApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
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;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableCaching
@EnableJpaAuditing
@EnableScheduling
@EnableBatchProcessing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import com.damyo.alpha.api.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;
Expand All @@ -30,6 +33,7 @@ public class InfoService {

private static final int POST_INFO_CONTRIBUTION_INCREMENT = 5;

@CacheEvict(value={"areaDetailsCache", "areaSummaryCache"}, key="#updateInfoRequest.smokingAreaId()", cacheManager="contentCacheManager")
public void updateInfo(UpdateInfoRequest updateInfoRequest, UserDetailsImpl details) {
SmokingArea sa = smokingAreaRepository.findSmokingAreaById(updateInfoRequest.smokingAreaId())
.orElseThrow(() -> {
Expand All @@ -38,6 +42,10 @@ public void updateInfo(UpdateInfoRequest updateInfoRequest, UserDetailsImpl deta
});
User user = details.getUser();
infoRepository.save(updateInfoRequest.toEntity(sa, user));
int size = infoRepository.findInfosBySmokingAreaId(updateInfoRequest.smokingAreaId()).size();
log.info("[test]: {}", size);
Float score = (sa.getScore() * size + updateInfoRequest.score()) / (size + 1);
smokingAreaRepository.updateSmokingAreaScoreById(score, sa.getId());
userService.updateContribution(user.getId(), POST_INFO_CONTRIBUTION_INCREMENT);
log.info("[Info]: info update complete");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package com.damyo.alpha.api.picture.controller.dto;

import com.damyo.alpha.api.picture.domain.Picture;
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 java.time.LocalDateTime;
public record PictureResponse (
Long id,
String pictureUrl,
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
LocalDateTime createdAt,
Long likes
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.HashOperations;
Expand Down Expand Up @@ -43,6 +44,7 @@ public class PictureService {
@Autowired
private RedisTemplate<String, Object> countTemplate;

@Cacheable(value="pictureCache", key="#id", cacheManager="contentCacheManager")
public PictureResponse getPicture(Long id) {
Picture picture = pictureRepository.findPictureById(id)
.orElseThrow(() -> {
Expand All @@ -53,12 +55,14 @@ public PictureResponse getPicture(Long id) {
return new PictureResponse(picture);
}

@Cacheable(value="pictureUserCache", key="#id", cacheManager="contentCacheManager")
public List<PictureResponse> getPicturesByUser(UUID id) {
List<Picture> pictures = pictureRepository.findPicturesByUser_id(id);
log.info("[Picture]: load pictures by user | {}", id);
return getPictureListResponse(pictures);
}

@Cacheable(value="pictureAreaCache", key="#id", cacheManager="contentCacheManager")
public List<PictureResponse> getPicturesBySmokingArea(String id, Long count) {
List<Picture> pictures = pictureRepository.findPicturesBySmokingArea_Id(id, count);
log.info("[Picture]: load pictures by area | {}", id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ public class SmokingAreaController {
private final SmokingAreaService smokingAreaService;
private final PictureService pictureService;
private final UserService userService;
private final InfoService infoService;
private final S3ImageService s3ImageService;
private final RedisTemplate<String, Object> redisTemplate;

Expand Down Expand Up @@ -108,13 +107,12 @@ public ResponseEntity<SmokingAreaAllResponse> getSmokingAreaDetailsById(
@Parameter(description = "흡연구역 ID", in = ParameterIn.PATH)
@PathVariable String smokingAreaId){
log.info("[Area]: /details/{}", smokingAreaId);
SmokingAreaDetailResponse area = smokingAreaService.findAreaById(smokingAreaId).toDTO();
InfoResponse info = infoService.getInfo(smokingAreaId);
Float avgScore = Math.round((info.score() + area.score()) / (info.size()+1) * 10) / 10.0F;

SmokingAreaDetailResponse area = smokingAreaService.findAreaDTOById(smokingAreaId);
List<PictureResponse> picList = pictureService.getPicturesBySmokingArea(smokingAreaId, 10L);

SmokingAreaAllResponse response = new SmokingAreaAllResponse(area.areaId(), area.name(), area.latitude(), area.longitude(), area.address(),
area.createdAt(), area.description(), avgScore, area.status(), area.opened(), area.closed(),
area.createdAt(), area.description(), area.score(), area.status(), area.opened(), area.closed(),
area.indoor(), area.outdoor(), picList);

return ResponseEntity.ok(response);
Expand All @@ -129,9 +127,9 @@ public ResponseEntity<SmokingAreaSummaryResponse> getSmokingAreaSummaryById(
@Parameter(description = "흡연구역 ID", in = ParameterIn.PATH)
@PathVariable String smokingAreaId){
log.info("[Area]: /summary/{}", smokingAreaId);
SmokingArea areaResponse = smokingAreaService.findAreaById(smokingAreaId);
SmokingAreaSummaryResponse response = smokingAreaService.findAreaSUMById(smokingAreaId);

return ResponseEntity.ok(areaResponse.toSUM());
return ResponseEntity.ok(response);
}

// 특정날짜이후 추가된 구역찾기
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package com.damyo.alpha.api.smokingarea.controller.dto;

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 java.math.BigDecimal;
import java.time.LocalDateTime;

Expand All @@ -9,6 +14,8 @@ public record SmokingAreaDetailResponse(
BigDecimal latitude,
BigDecimal longitude,
String address,
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
LocalDateTime createdAt,
Boolean status,
String description,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ public interface SmokingAreaRepository extends JpaRepository<SmokingArea, String
"WHERE sa.id = :id")
void updateSmokingAreaAddressById(@Param("address") String address, @Param("id") String id);

@Transactional
@Modifying(clearAutomatically = true)
@Query("UPDATE SmokingArea sa SET sa.score = :score " +
"WHERE sa.id = :id")
void updateSmokingAreaScoreById(@Param("score") Float score, @Param("id") String id);

@Modifying(clearAutomatically = true)
@Query("UPDATE SmokingArea sa SET sa.description = :description " +
"WHERE sa.id = :id")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.damyo.alpha.api.smokingarea.exception.AreaException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.scheduling.annotation.Scheduled;
Expand Down Expand Up @@ -37,13 +38,24 @@ public List<SmokingAreaSummaryResponse> findAreaAll(){
return areaResponses;
}

public SmokingArea findAreaById(String smokingAreaId) {
@Cacheable(value="areaDetailsCache", key="#smokingAreaId", cacheManager="contentCacheManager")
public SmokingAreaDetailResponse findAreaDTOById(String smokingAreaId) {
SmokingArea area = smokingAreaRepository.findSmokingAreaById(smokingAreaId)
.orElseThrow(() -> {
log.error("[Area]: area not found by id | {}", smokingAreaId);
log.error("[Area]: area detail not found by id | {}", smokingAreaId);
return new AreaException(NOT_FOUND_ID);
});
return area;
return area.toDTO();
}

@Cacheable(value="areaSummaryCache", key="#smokingAreaId", cacheManager="contentCacheManager")
public SmokingAreaSummaryResponse findAreaSUMById(String smokingAreaId) {
SmokingArea area = smokingAreaRepository.findSmokingAreaById(smokingAreaId)
.orElseThrow(() -> {
log.error("[Area]: area summary not found by id | {}", smokingAreaId);
return new AreaException(NOT_FOUND_ID);
});
return area.toSUM();
}

public List<SmokingAreaSummaryResponse> findAreaByCreatedAt(LocalDateTime createdAt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.damyo.alpha.api.user.domain.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.damyo.alpha.api.user.domain.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/com/damyo/alpha/global/config/RedisCacheConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.damyo.alpha.global.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
@EnableCaching
public class RedisCacheConfig {
@Bean
public CacheManager contentCacheManager(RedisConnectionFactory rcf) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.entryTtl(Duration.ofMinutes(30L));

return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(rcf).cacheDefaults(redisCacheConfiguration).build();
}
}

0 comments on commit ad66ae2

Please sign in to comment.