Skip to content

Commit

Permalink
Merge pull request #40 from inu-appcenter/wonjeong#39-feat-redis
Browse files Browse the repository at this point in the history
[Feat] 레디스로 서버의 응답속도를 개선합니다.
  • Loading branch information
NARUBROWN authored Jan 24, 2024
2 parents eaead7d + 562a83a commit fd4c906
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 7 deletions.
6 changes: 5 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
}

group = 'home.inuappcenter.kr'
version = '0.1.5-SNAPSHOT'
version = '0.5.0-SNAPSHOT'

java {
sourceCompatibility = '11'
Expand Down Expand Up @@ -52,6 +52,10 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
// Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis:2.7.14'
// spring cache
implementation 'org.springframework.boot:spring-boot-starter-cache:2.7.14'
}

tasks.named('test') {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/server/inuappcenter/kr/HomepageApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import io.swagger.v3.oas.annotations.servers.Server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@OpenAPIDefinition(servers =
{@Server(url = "https://server.inuappcenter.kr/", description = "Default Server URL"),
@Server(url = "/", description = "Development Server URL")})
@SpringBootApplication
@EnableCaching
public class HomepageApplication {

public static void main(String[] args) {
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/server/inuappcenter/kr/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package server.inuappcenter.kr.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.redis.host}")
private String host;

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

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

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

return redisTemplate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package server.inuappcenter.kr.data.dto.response;

import lombok.Getter;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;

import java.time.LocalDateTime;

@Getter
@RedisHash(value = "board")
public abstract class BoardResponseDto {
@Id
protected Long id;
protected String body;
protected LocalDateTime createdDate;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package server.inuappcenter.kr.data.repository.redis;

import org.springframework.data.repository.CrudRepository;
import server.inuappcenter.kr.data.dto.response.BoardResponseDto;

public interface BoardResponseRedisRepository<T extends BoardResponseDto> extends CrudRepository<T, Long> {
BoardResponseDto getById(Long id);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package server.inuappcenter.kr.service;

import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import server.inuappcenter.kr.data.domain.board.Image;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import server.inuappcenter.kr.data.dto.response.BoardResponseDto;
import server.inuappcenter.kr.data.repository.BoardRepository;
import server.inuappcenter.kr.data.repository.ImageRepository;
import server.inuappcenter.kr.data.repository.redis.BoardResponseRedisRepository;
import server.inuappcenter.kr.exception.customExceptions.CustomNotFoundException;

import javax.servlet.http.HttpServletRequest;
Expand All @@ -25,11 +26,18 @@ public class BoardService {
private final BoardRepository<Board> boardRepository;
private final ImageRepository imageRepository;
private final HttpServletRequest request;
private final BoardResponseRedisRepository<BoardResponseDto> boardResponseRedisRepository;

@Transactional(readOnly = true)
public BoardResponseDto findBoard(Long id) {
Board result = boardRepository.findById(id).orElseThrow(() -> new CustomNotFoundException("ID에 해당되는 보드가 없습니다."));
return result.createResponse(request);
return boardResponseRedisRepository.findById(id).orElseGet(
() -> {
Board result = boardRepository.findById(id).orElseThrow(() -> new CustomNotFoundException("ID에 해당되는 보드가 없습니다."));
BoardResponseDto resultDto = result.createResponse(request);
boardResponseRedisRepository.save(resultDto);
return resultDto;
}
);
}

@Transactional
Expand All @@ -47,6 +55,7 @@ public CommonResponseDto deleteBoard(Long id) {

@Transactional
public CommonResponseDto updateBoard(Long board_id, List<Long> image_id, BoardRequestDto boardRequestDto) {
boardResponseRedisRepository.deleteById(board_id);
Board foundBoard = boardRepository.findById(board_id).orElseThrow(() -> new CustomNotFoundException("The requested ID was not found."));
// 사용자가 multipart를 같이 보냈는지 확인
if (boardRequestDto.getMultipartFiles() != null || image_id != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import server.inuappcenter.kr.data.domain.board.Board;
Expand Down
10 changes: 8 additions & 2 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
spring:
redis:
port: 5379
host: na2ru2.me
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
url: jdbc:mysql://localhost:3306/appcenter
username: dev
url: jdbc:mysql://na2ru2.me:6306/appcenter
password: test1234
jpa:
hibernate:
ddl-auto: none
show-sql: true
open-in-view: false
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
sql:
init:
mode: always
Expand Down
30 changes: 30 additions & 0 deletions src/test/java/server/inuappcenter/kr/RedisTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package server.inuappcenter.kr;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import server.inuappcenter.kr.data.dto.response.BoardResponseDto;
import server.inuappcenter.kr.data.dto.response.FaqBoardResponseDto;
import server.inuappcenter.kr.data.repository.redis.BoardResponseRedisRepository;
import server.inuappcenter.kr.exception.customExceptions.CustomNotFoundException;

import java.time.LocalDateTime;

import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest
public class RedisTest {
@Autowired
private BoardResponseRedisRepository<BoardResponseDto> boardResponseRedisRepository;

@Test
void save() {
BoardResponseDto boardResponseDto = new FaqBoardResponseDto(
1L, "서버", "질문입니다.", "대답입니다.", LocalDateTime.now(), LocalDateTime.now()
);
boardResponseRedisRepository.save(boardResponseDto);

BoardResponseDto findResponse = boardResponseRedisRepository.findById(boardResponseDto.getId()).orElseThrow(() -> new CustomNotFoundException("ID가 없습니다."));
assertEquals(boardResponseDto.getId(), findResponse.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import server.inuappcenter.kr.data.repository.ImageRepository;
import server.inuappcenter.kr.data.repository.IntroBoardRepository;
import server.inuappcenter.kr.service.boardService.BoardService;
import server.inuappcenter.kr.service.boardService.IntroBoardService;
import server.inuappcenter.kr.service.boardService.impl.IntroBoardServiceImpl;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
Expand All @@ -27,7 +27,7 @@ public class IntroBoardServiceTest {
@Mock
private ImageRepository imageRepository;
@InjectMocks
private IntroBoardService introBoardService;
private IntroBoardServiceImpl introBoardService;

@Mock
private HttpServletRequest request = new MockHttpServletRequest();
Expand Down

0 comments on commit fd4c906

Please sign in to comment.