728x90
1.RedisConfig
Redis를 설정하여 Redis 서버와 연결하고 값은 JSON 형식으로 직렬화하여 Redis에 저장할 수 있도록 설정한 파일을 생성했다.
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
2.incrementProductView
1시간 동안 유지되는 Redis를 통해 productId를 받아서 조회수를 저장하도록 서비스에 메소드를 만들었다.
// 조회수 증가
public void incrementProductView(Long productId) {
String key = "product:views";
String product = productId.toString();
// 조회수 증가
redisTemplate.opsForZSet().incrementScore(key, product, 1);
//1시간(3600초) 동안만 유지
redisTemplate.expire(key, 1, TimeUnit.HOURS);
}
2-1.엔드포인트에 적용
이제 이걸 개별 상품을 조회하는 엔드포인트에 넣는다
(redis 를 사용하는 service 이름이 rateLimiterSerive로 되어있지만 리펙토링예정)
//상품 상세조회
@GetMapping("/{productId}")
@RateLimit(value = 5, timeWindow = 1)
public ResponseEntity<ProductResponseDTO> getProductItemDetail(@PathVariable Long productId){
ProductResponseDTO responseDTO = productService.getProductDetail(productId);
productService.incrementProductView(productId);
return ResponseEntity.status(HttpStatus.OK).body(responseDTO);
}
3.인기 제품 조회
상품 조회수를 기준으로 Redis에 저장된 인기 상품 리스트를 가져와, 해당 상품들의 정보를 데이터베이스에서 조회하여 반환하는 메소드를 서비스에 만들었다.
// 인기 상품 상위 10개 조회
public List<ProductResponseDTO> getPopularProducts() {
String key = "product:views";
Set<Object> topProducts = redisTemplate.opsForZSet().reverseRange(key, 0, 9);
List<Long> productIds = topProducts.stream()
.map(productId -> Long.parseLong((String) productId))
.collect(Collectors.toList());
List<Product> products = productRepository.findByIdIn(productIds);
Map<Long, Product> productMap = products.stream()
.collect(Collectors.toMap(Product::getId, product -> product));
List<ProductResponseDTO> response = productIds.stream()
.map(productId -> ProductResponseDTO.fromEntity(productMap.get(productId)))
.collect(Collectors.toList());
return response;
}
3-1.컨트롤러
@GetMapping("/top")
public ResponseEntity<List<ProductResponseDTO>> getPopularProducts() {
List<ProductResponseDTO> topProducts = productService.getPopularProducts();
return ResponseEntity.ok(topProducts);
}
728x90
'BackEnd > SpringBoot' 카테고리의 다른 글
[SpringBoot] 이미지 업로드 기능만들기 (0) | 2025.03.16 |
---|---|
[SpringBoot] Rate Limiting 기능, AOP 적용,어노테이션 만들기 (0) | 2025.03.12 |
[SpringBoot] Redis 로 Spring Cache 추가 (0) | 2025.03.11 |
728x90

1.RedisConfig
Redis를 설정하여 Redis 서버와 연결하고 값은 JSON 형식으로 직렬화하여 Redis에 저장할 수 있도록 설정한 파일을 생성했다.
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
2.incrementProductView
1시간 동안 유지되는 Redis를 통해 productId를 받아서 조회수를 저장하도록 서비스에 메소드를 만들었다.
// 조회수 증가
public void incrementProductView(Long productId) {
String key = "product:views";
String product = productId.toString();
// 조회수 증가
redisTemplate.opsForZSet().incrementScore(key, product, 1);
//1시간(3600초) 동안만 유지
redisTemplate.expire(key, 1, TimeUnit.HOURS);
}
2-1.엔드포인트에 적용
이제 이걸 개별 상품을 조회하는 엔드포인트에 넣는다
(redis 를 사용하는 service 이름이 rateLimiterSerive로 되어있지만 리펙토링예정)
//상품 상세조회
@GetMapping("/{productId}")
@RateLimit(value = 5, timeWindow = 1)
public ResponseEntity<ProductResponseDTO> getProductItemDetail(@PathVariable Long productId){
ProductResponseDTO responseDTO = productService.getProductDetail(productId);
productService.incrementProductView(productId);
return ResponseEntity.status(HttpStatus.OK).body(responseDTO);
}
3.인기 제품 조회
상품 조회수를 기준으로 Redis에 저장된 인기 상품 리스트를 가져와, 해당 상품들의 정보를 데이터베이스에서 조회하여 반환하는 메소드를 서비스에 만들었다.
// 인기 상품 상위 10개 조회
public List<ProductResponseDTO> getPopularProducts() {
String key = "product:views";
Set<Object> topProducts = redisTemplate.opsForZSet().reverseRange(key, 0, 9);
List<Long> productIds = topProducts.stream()
.map(productId -> Long.parseLong((String) productId))
.collect(Collectors.toList());
List<Product> products = productRepository.findByIdIn(productIds);
Map<Long, Product> productMap = products.stream()
.collect(Collectors.toMap(Product::getId, product -> product));
List<ProductResponseDTO> response = productIds.stream()
.map(productId -> ProductResponseDTO.fromEntity(productMap.get(productId)))
.collect(Collectors.toList());
return response;
}
3-1.컨트롤러
@GetMapping("/top")
public ResponseEntity<List<ProductResponseDTO>> getPopularProducts() {
List<ProductResponseDTO> topProducts = productService.getPopularProducts();
return ResponseEntity.ok(topProducts);
}
728x90
'BackEnd > SpringBoot' 카테고리의 다른 글
[SpringBoot] 이미지 업로드 기능만들기 (0) | 2025.03.16 |
---|---|
[SpringBoot] Rate Limiting 기능, AOP 적용,어노테이션 만들기 (0) | 2025.03.12 |
[SpringBoot] Redis 로 Spring Cache 추가 (0) | 2025.03.11 |