Skip to content

Commit

Permalink
Merge pull request #5 from fr35wo/feature/board
Browse files Browse the repository at this point in the history
feat: Redis 연동 & 조회수 중복 증가 방지 기능 구현
  • Loading branch information
fr35wo authored Apr 3, 2024
2 parents 9925055 + 30a35d3 commit 635b269
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 2 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ dependencies {
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

// Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
}

jar {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.example.copro.board.exception.NotBoardOwnerException;
import com.example.copro.board.exception.ScrapNotFoundException;
import com.example.copro.comment.domain.repository.CommentRepository;
import com.example.copro.global.redis.application.RedisService;
import com.example.copro.image.domain.Image;
import com.example.copro.image.domain.repository.ImageRepository;
import com.example.copro.member.domain.Member;
Expand Down Expand Up @@ -51,6 +52,8 @@ public class BoardService {

private final NotificationRepository notificationRepository;

private final RedisService redisService;

public BoardListRspDto findAll(String category, Pageable pageable) {
//Page<Board> boards = boardRepository.findAllByCategory(Category.valueOf(category), pageable);
Page<BoardDto> boards = boardRepository.findAllWithCommentCount(Category.valueOf(category), pageable);
Expand Down Expand Up @@ -163,7 +166,13 @@ public BoardListRspDto findByTitleContaining(String query, Pageable pageable) {
public BoardResDto getBoard(Member member, Long boardId) {
Member getMember = memberRepository.findById(member.getMemberId()).orElseThrow(MemberNotFoundException::new);
Board board = boardRepository.findById(boardId).orElseThrow(() -> new BoardNotFoundException(boardId));
board.updateViewCount();

if (!board.getMember().getMemberId().equals(getMember.getMemberId())) {
boolean isFirstView = redisService.checkAndAddViewByMember(getMember.getMemberId(), boardId);
if (isFirstView) {
board.updateViewCount();
}
}

boolean isHeart = memberHeartBoardRepository.existsByMemberAndBoard(getMember, board);
boolean isScrap = memberScrapBoardRepository.existsByMemberAndBoard(getMember, board);
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/com/example/copro/global/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.example.copro.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.host}")
private String host;

@Value("${spring.data.redis.port}")
private int port;

@Value("${spring.profiles.active}")
private String namespace;

@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}

@Bean
public RedisTemplate<String, String> redisTemplate() {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}

public String getNamespace() {
return namespace;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.example.copro.global.redis.application;

import com.example.copro.global.config.RedisConfig;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

@Service
public class RedisService {
private final RedisTemplate<String, String> redisTemplate;
private final RedisConfig redisConfig;

public RedisService(RedisTemplate<String, String> redisTemplate, RedisConfig redisConfig) {
this.redisTemplate = redisTemplate;
this.redisConfig = redisConfig;
}

public boolean checkAndAddViewByMember(Long memberId, Long boardId) {
String namespace = redisConfig.getNamespace();
String redisKey = namespace + ":boardView:" + boardId;
String redisMemberKey = namespace + ":memberView:" + memberId;

List<String> memberViewList = getValuesList(redisMemberKey);

if (!memberViewList.contains(redisKey)) {
setValuesListWithExpire(redisMemberKey, redisKey, Duration.ofHours(24));
return true;
}
return false;
}

public void setValuesListWithExpire(String key, String data, Duration duration) {
redisTemplate.opsForList().rightPush(key, data);
redisTemplate.expire(key, duration);
}

public List<String> getValuesList(String key) {
Long len = redisTemplate.opsForList().size(key);
return len == 0 ? new ArrayList<>() : redisTemplate.opsForList().range(key, 0, len-1);
}

}
10 changes: 9 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ FIREBASE_KEY: ${FIREBASE_KEY}
spring:
profiles:
active: prod
data:
redis:
host: ${spring.data.redis.host}
port: ${spring.data.redis.port}

datasource:
url: ${spring.datasource.url}
Expand Down Expand Up @@ -78,6 +82,10 @@ admin:
spring:
profiles:
active: dev
data:
redis:
host: ${spring.data.redis.host}
port: ${spring.data.redis.port}

datasource:
url: ${spring.datasource.url}
Expand All @@ -97,4 +105,4 @@ logging:

myapp:
api-url: ${myapp.api-url}
local-url: ${myapp.local-url}
local-url: ${myapp.local-url}

0 comments on commit 635b269

Please sign in to comment.