Skip to content

Commit

Permalink
Merge pull request #38 from inu-appcenter/34-feat-Improved-scalability
Browse files Browse the repository at this point in the history
[Feat] improved scalability
  • Loading branch information
NARUBROWN authored Jan 18, 2024
2 parents 48151b6 + 394d4ec commit 1df2abf
Show file tree
Hide file tree
Showing 17 changed files with 252 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ public ResponseEntity<CommonResponseDto> saveFaq(final @RequestBody @Valid FaqBo

@Operation(summary = "FAQ 한 개 수정", description = "수정할 FAQ JSON을 보내주세요")
@PatchMapping
public ResponseEntity<FaqBoardResponseDto> updateFaq(final @RequestBody @Valid FaqBoardRequestDto faqBoardRequestDto,
public ResponseEntity<CommonResponseDto> updateFaq(final @RequestBody @Valid FaqBoardRequestDto faqBoardRequestDto,
final Long id) {
log.info("사용자가 id: "+ id + "을(를) 가진 FAQ를 수정하도록 요청했습니다.\n" +
"FaqBoardRequestDto의 내용: "+ faqBoardRequestDto.toString());
FaqBoardResponseDto faqBoardResponseDto = faqBoardService.updateFaqBoard(id, faqBoardRequestDto);
return ResponseEntity.status(HttpStatus.OK).body(faqBoardResponseDto);
CommonResponseDto commonResponseDto = boardService.updateBoard(id, null, faqBoardRequestDto);
return ResponseEntity.status(HttpStatus.OK).body(commonResponseDto);
}

@Operation(summary = "FAQ 한 개 삭제", description = "삭제할 faq_id를 입력해주세요")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,21 @@ public ResponseEntity<List<IntroBoardResponseDto>> findAllBoard() {
return ResponseEntity.status(HttpStatus.OK).body(dto_list);
}

@Operation(summary = "게시글 (1개) 수정")
@PatchMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<IntroBoardResponseDto> updateBoard(
final @ModelAttribute @Valid IntroBoardRequestDto introBoardRequestDto,
BindingResult bindingResult,
final @Parameter(name = "id", description = "그룹 ID", required = true) Long id) {

@Operation(summary = "게시글 수정 테스트")
@PatchMapping(path = {"/{photo_ids}", "/"}, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<CommonResponseDto> updateBoard(
final @PathVariable(name = "photo_ids", required = false) List<Long> photo_ids,
final @ModelAttribute @Valid IntroBoardRequestDto introBoardRequestDto,
BindingResult bindingResult,
final @Parameter(name = "board_id") Long board_id) {
if(bindingResult.hasErrors()) {
throw new CustomModelAttributeException(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
}

log.info("사용자가 id: "+ id + "을(를) 가진 IntroBoard를 수정하도록 요청했습니다.\n" +
log.info("사용자가 id: "+ board_id + "을(를) 가진 IntroBoard를 수정하도록 요청했습니다.\n" +
"IntroBoardRequestDto의 내용: "+ introBoardRequestDto.toString());

IntroBoardResponseDto introBoardResponseDto = introBoardService.updateIntroBoard(introBoardRequestDto, id);
return ResponseEntity.status(HttpStatus.OK).body(introBoardResponseDto);
CommonResponseDto commonResponseDto = boardService.updateBoard(board_id, photo_ids, introBoardRequestDto);
return ResponseEntity.status(HttpStatus.OK).body(commonResponseDto);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,20 @@ public ResponseEntity<CommonResponseDto> saveBoard(final @ModelAttribute @Valid
}
}

@Operation(summary = "게시글 (1개) 수정", description = "1개의 사진이 필수적으로 필요합니다.")
@PatchMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<PhotoBoardResponseDto> updateBoard(
@Operation(summary = "게시글 수정 테스트")
@PatchMapping(path = {"/{photo_ids}", "/"}, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<CommonResponseDto> updateBoard(
final @PathVariable(name = "photo_ids", required = false) List<Long> photo_ids,
final @ModelAttribute @Valid PhotoBoardRequestDto photoBoardRequestDto,
BindingResult bindingResult,
final @Parameter(name = "id", description = "게시판 ID", required = true) Long id) {

final @Parameter(name = "board_id") Long board_id) {
if(bindingResult.hasErrors()) {
throw new CustomModelAttributeException(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
} else {
log.info("사용자가 id: "+ id + "을(를) 가진 PhotoBoard를 수정하도록 요청했습니다.\n" +
"PhotoBoardRequestDto의 내용: "+ photoBoardRequestDto.toString());
PhotoBoardResponseDto photoBoardResponseDto = photoBoardService.updatePhotoBoard(photoBoardRequestDto, id);
return ResponseEntity.status(HttpStatus.OK).body(photoBoardResponseDto);
}
log.info("사용자가 id: "+ board_id + "을(를) 가진 PhotoBoard를 수정하도록 요청했습니다.\n" +
"PhotoBoardRequestDto의 내용: "+ photoBoardRequestDto.toString());
CommonResponseDto commonResponseDto = boardService.updateBoard(board_id, photo_ids, photoBoardRequestDto);
return ResponseEntity.status(HttpStatus.OK).body(commonResponseDto);
}

@Operation(summary = "게시글 (1개) 삭제하기", description = "삭제할 게시글의 id를 입력해주세요")
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/server/inuappcenter/kr/data/domain/board/Board.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import lombok.Getter;
import server.inuappcenter.kr.common.data.domain.BaseTimeEntity;
import server.inuappcenter.kr.data.dto.request.BoardRequestDto;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
Expand All @@ -15,4 +18,12 @@ public abstract class Board extends BaseTimeEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String body;

public abstract void modifyBoard(BoardRequestDto boardRequestDto);

public abstract void updateImage(List<Image> images);

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "board_id")
private List<Image> images = new ArrayList<>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import server.inuappcenter.kr.data.dto.request.BoardRequestDto;
import server.inuappcenter.kr.data.dto.request.FaqBoardRequestDto;
import server.inuappcenter.kr.data.dto.response.FaqBoardResponseDto;

import javax.persistence.Entity;
import java.util.List;

@Getter
@Entity
Expand Down Expand Up @@ -40,4 +42,12 @@ public FaqBoardResponseDto toResponseDto(FaqBoard faqBoard) {
);
}

@Override
public void modifyBoard(BoardRequestDto boardRequestDto) {
this.updateFaqBoard((FaqBoardRequestDto) boardRequestDto);
}

@Override
public void updateImage(List<Image> image) {
}
}
29 changes: 23 additions & 6 deletions src/main/java/server/inuappcenter/kr/data/domain/board/Image.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,8 @@ public class Image {
private Long id;

@ManyToOne
@JoinColumn(name = "intro_board_id", updatable = false, insertable = false)
private IntroBoard introBoard;

@ManyToOne
@JoinColumn(name = "photo_board_id", updatable = false, insertable = false)
private PhotoBoard photoBoard ;
@JoinColumn(name = "board_id", updatable = false, insertable = false)
private Board board;

@Column(name = "original_file_name")
private String originalFileName;
Expand All @@ -47,6 +43,17 @@ public Image(String originalFilename, byte[] bytes, long size) {
this.fileSize = size;
}

public Image(MultipartFile multipartFile) {
try {
this.originalFileName = multipartFile.getOriginalFilename();
this.imageData = ImageUtils.compressImage(multipartFile.getBytes());
this.fileSize = multipartFile.getSize();
} catch (IOException e) {
throw new RuntimeException("사진을 처리하던 중 오류가 발생했습니다.");
}

}

public void updateIdForTest(Long id) {
this.id = id;
}
Expand Down Expand Up @@ -75,5 +82,15 @@ public Image returnMultipartToEntity(MultipartFile multipartFile) throws IOExcep
return new Image(multipartFile.getOriginalFilename(), ImageUtils.compressImage(multipartFile.getBytes()), multipartFile.getSize());
}

public void updateImage(MultipartFile multipartFile) {
try {
this.imageData = ImageUtils.compressImage(multipartFile.getBytes());
this.fileSize = multipartFile.getSize();
this.originalFileName = multipartFile.getOriginalFilename();
} catch (IOException e) {
throw new RuntimeException("사진을 처리하던 중 오류가 발생했습니다.");
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.web.multipart.MultipartFile;
import server.inuappcenter.kr.data.dto.request.BoardRequestDto;
import server.inuappcenter.kr.data.dto.request.IntroBoardRequestDto;
import server.inuappcenter.kr.data.dto.response.IntroBoardResponseDto;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -27,8 +25,6 @@ public class IntroBoard extends Board {
public String appleStoreLink;
public String body;

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "intro_board_id")
private List<Image> images = new ArrayList<>();

public IntroBoard(IntroBoardRequestDto introBoardRequestDto) {
Expand Down Expand Up @@ -68,6 +64,7 @@ public IntroBoardResponseDto toBoardResponseDto(IntroBoard introBoard, String im
.build();
}

// 새 이미지 객체를 만들어 PhotoBoard(부모객체)와 매핑시킵니다.
public List<Image> mappingPhotoAndEntity(List<MultipartFile> multipartFiles) {
List<Image> imageEntityList = new ArrayList<>();
for (MultipartFile file: multipartFiles) {
Expand All @@ -80,4 +77,15 @@ public List<Image> mappingPhotoAndEntity(List<MultipartFile> multipartFiles) {
imageEntityList.get(0).isThumbnail();
return imageEntityList;
}

@Override
public void modifyBoard(BoardRequestDto boardRequestDto) {
// updateBoard 메소드를 통해 IntroBoard의 내용을 업데이트 합니다.
this.updateBoard((IntroBoardRequestDto) boardRequestDto);
}

@Override
public void updateImage(List<Image> images) {
this.images.addAll(images);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.web.multipart.MultipartFile;
import server.inuappcenter.kr.data.dto.request.BoardRequestDto;
import server.inuappcenter.kr.data.dto.request.PhotoBoardRequestDto;
import server.inuappcenter.kr.data.dto.response.PhotoBoardResponseDto;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -24,8 +22,6 @@ public class PhotoBoard extends Board {

private String body;

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "photo_board_id")
private List<Image> images = new ArrayList<>();

public PhotoBoard(PhotoBoardRequestDto photoBoardRequestDto) {
Expand Down Expand Up @@ -67,4 +63,13 @@ public List<Image> mappingPhotoAndEntity(List<MultipartFile> multipartFiles) {
}


@Override
public void modifyBoard(BoardRequestDto photoBoardRequestDto) {
this.updateBoard((PhotoBoardRequestDto) photoBoardRequestDto);
}

@Override
public void updateImage(List<Image> images) {
this.images = images;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import server.inuappcenter.kr.data.domain.board.IntroBoard;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

@Getter
Expand Down Expand Up @@ -49,9 +48,8 @@ public class IntroBoardRequestDto extends BoardRequestDto{
private String body;

@Schema(
description = "이미지를 배열로 받습니다."
description = "이미지를 배열로 받습니다. '첫번째 요소는 아이콘입니다.'"
)
@NotNull(message = "이미지가 최소 1개 이상 필요합니다. (첫번째 이미지는 썸네일입니다.)")
private List<MultipartFile> multipartFiles;

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package server.inuappcenter.kr.data.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import server.inuappcenter.kr.data.domain.board.Board;
import server.inuappcenter.kr.data.domain.board.Image;
import server.inuappcenter.kr.data.domain.board.IntroBoard;
import server.inuappcenter.kr.data.domain.board.PhotoBoard;

import java.util.List;

@Repository
public interface ImageRepository extends JpaRepository<Image, Long> {
List<Image> findAllByIsThumbnailTrue();

/*
List<Image> findByIntroBoard(IntroBoard introBoard);
List<Image> findByPhotoBoard(PhotoBoard photoBoard);
*/

@Query("SELECT i FROM Image i WHERE i.id IN :imageIds AND i.board = :board")
List<Image> findByImageIdsAndBoard(@Param("imageIds") List<Long> imageIds, @Param("board") Board board);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,24 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import server.inuappcenter.kr.common.data.dto.CommonResponseDto;
import server.inuappcenter.kr.data.domain.board.Board;
import server.inuappcenter.kr.data.domain.board.Image;
import server.inuappcenter.kr.data.dto.request.BoardRequestDto;
import server.inuappcenter.kr.data.repository.BoardRepository;
import server.inuappcenter.kr.data.repository.ImageRepository;
import server.inuappcenter.kr.exception.customExceptions.CustomNotFoundException;

import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
@Slf4j
public class BoardService {
private final BoardRepository<Board> boardRepository;
private final ImageRepository imageRepository;

@Transactional
public Board getBoard(Long id) {
Expand All @@ -34,4 +41,50 @@ public CommonResponseDto deleteBoard(Long id) {
return new CommonResponseDto("id: " + id + " has been successfully deleted.");
}

@Transactional
public CommonResponseDto updateBoard(Long board_id, List<Long> image_id, BoardRequestDto boardRequestDto) {
Board foundBoard = boardRepository.findById(board_id).orElseThrow(() -> new CustomNotFoundException("The requested ID was not found."));
// 사용자가 multipart를 같이 보냈는지 확인
if (boardRequestDto.getMultipartFiles() != null || image_id != null) {
// 이미지 레포지토리에서 사용자가 보낸 ID로 조회를 먼저 진행하여, 찾아진 이미지 목록을 가짐
List<Image> foundImageList = imageRepository.findByImageIdsAndBoard(image_id, foundBoard);
// multipart에서 이미지를 가져와 데이터와 정보를 해당 image에 업데이트
for (Image image: foundImageList) {
for (MultipartFile multipartFile: boardRequestDto.getMultipartFiles()) {
image.updateImage(multipartFile);
}
}
// DB에 저장되지 않은 이미지에 대한 처리들을 진행해야 함
// 먼저 DB에서 찾아진 ID에 대한 목록을 만들어줌
List<Long> foundImageIds = new ArrayList<>();
for (Image image : foundImageList) {
// 찾아진 이미지 목록에서 id를 가져와 찾아진 id 목록에 추가함
foundImageIds.add(image.getId());
}
// 찾아진 ID 목록에 존재하지 않는 ID를 얻어야 하기 때문에 없는 이미지 ID 목록을 만들어줌
List<Long> missingImageIds = new ArrayList<>();
for (Long id : image_id) {
// 찾아진 Id 목록에 사용자가 보낸 ID가 존재하지 않는다면
if (!foundImageIds.contains(id)) {
// 이 ID를 없는 이미지 ID에 추가함
missingImageIds.add(id);
}
}
// 존재하지 않는 ID 목록 수 만큼 새로운 이미지 객체를 만들어줌
List<Image> newImageList = new ArrayList<>();
for (int i = 0; i < missingImageIds.size(); i++) {
newImageList.add(new Image(boardRequestDto.getMultipartFiles().get(i)));
}
// 이 이미지 객체는 Board와 매핑되어 저장되어야 함
// 따라서 새로운 이미지를 수정할 Board와 매핑시킨다.
foundBoard.updateImage(newImageList);
// 변경된 이미지 정보를 저장
imageRepository.saveAll(foundImageList);
}
// 이미지가 없을 경우 글 내용만 수정한다.
foundBoard.modifyBoard(boardRequestDto);
boardRepository.save(foundBoard);
return new CommonResponseDto("id: " + board_id + " has been successfully modified.");
}

}
Loading

0 comments on commit 1df2abf

Please sign in to comment.