From 53f2b5d2714e4eacc52274cb9868d0ad7f361500 Mon Sep 17 00:00:00 2001 From: koungq Date: Wed, 31 Jul 2024 20:39:45 +0900 Subject: [PATCH] =?UTF-8?q?Refactor:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weeth/domain/account/dto/AccountDTO.java | 1 - .../weeth/domain/account/entity/Receipt.java | 6 ++-- .../domain/account/mapper/ReceiptMapper.java | 11 ++---- .../account/service/ReceiptService.java | 3 +- .../weeth/domain/event/entity/Event.java | 14 +++----- .../file/converter/FileListConverter.java | 35 +++++++++++++++++++ .../leets/weeth/domain/file/entity/File.java | 24 ------------- .../file/repository/FileRepository.java | 8 ----- .../domain/file/service/FileService.java | 34 +++++++----------- .../domain/notice/dto/ResponseNotice.java | 3 +- .../domain/notice/mapper/NoticeMapper.java | 3 +- .../domain/notice/service/NoticeService.java | 7 ++-- .../domain/post/dto/ResponsePostDTO.java | 6 ++-- .../leets/weeth/domain/post/entity/Post.java | 17 ++++----- .../domain/post/service/PostService.java | 4 +-- src/main/resources/application-local.yml | 4 +-- 16 files changed, 79 insertions(+), 101 deletions(-) create mode 100644 src/main/java/leets/weeth/domain/file/converter/FileListConverter.java delete mode 100644 src/main/java/leets/weeth/domain/file/entity/File.java delete mode 100644 src/main/java/leets/weeth/domain/file/repository/FileRepository.java diff --git a/src/main/java/leets/weeth/domain/account/dto/AccountDTO.java b/src/main/java/leets/weeth/domain/account/dto/AccountDTO.java index 587dd747..a13b4901 100644 --- a/src/main/java/leets/weeth/domain/account/dto/AccountDTO.java +++ b/src/main/java/leets/weeth/domain/account/dto/AccountDTO.java @@ -1,6 +1,5 @@ package leets.weeth.domain.account.dto; -import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import java.util.List; diff --git a/src/main/java/leets/weeth/domain/account/entity/Receipt.java b/src/main/java/leets/weeth/domain/account/entity/Receipt.java index 4a1b99f2..dbafb842 100644 --- a/src/main/java/leets/weeth/domain/account/entity/Receipt.java +++ b/src/main/java/leets/weeth/domain/account/entity/Receipt.java @@ -1,7 +1,7 @@ package leets.weeth.domain.account.entity; import jakarta.persistence.*; -import leets.weeth.domain.file.entity.File; +import leets.weeth.domain.file.converter.FileListConverter; import leets.weeth.global.common.entity.BaseEntity; import lombok.*; @@ -24,8 +24,8 @@ public class Receipt extends BaseEntity { private String description; - @OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true) - private List images; + @Convert(converter = FileListConverter.class) + private List images; private LocalDate date; diff --git a/src/main/java/leets/weeth/domain/account/mapper/ReceiptMapper.java b/src/main/java/leets/weeth/domain/account/mapper/ReceiptMapper.java index 24c39366..98291a6a 100644 --- a/src/main/java/leets/weeth/domain/account/mapper/ReceiptMapper.java +++ b/src/main/java/leets/weeth/domain/account/mapper/ReceiptMapper.java @@ -3,7 +3,6 @@ import leets.weeth.domain.account.dto.ReceiptDTO; import leets.weeth.domain.account.entity.Account; import leets.weeth.domain.account.entity.Receipt; -import leets.weeth.domain.file.entity.File; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingConstants; @@ -14,16 +13,10 @@ @Mapper(componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE) public interface ReceiptMapper { - @Mapping(target = "images", expression = "java( toUrls(receipt.getImages()) )") ReceiptDTO.Response to(Receipt receipt); + @Mapping(target = "id", ignore = true) @Mapping(target = "description", source = "dto.description") @Mapping(target = "account", source = "account") - Receipt from(ReceiptDTO.Spend dto, Account account, List images); - - default List toUrls(List images) { - return images.stream() - .map(File::getUrl) - .toList(); - } + Receipt from(ReceiptDTO.Spend dto, Account account, List images); } \ No newline at end of file diff --git a/src/main/java/leets/weeth/domain/account/service/ReceiptService.java b/src/main/java/leets/weeth/domain/account/service/ReceiptService.java index 1a2fcfec..7e5fca7f 100644 --- a/src/main/java/leets/weeth/domain/account/service/ReceiptService.java +++ b/src/main/java/leets/weeth/domain/account/service/ReceiptService.java @@ -6,7 +6,6 @@ import leets.weeth.domain.account.mapper.ReceiptMapper; import leets.weeth.domain.account.repository.AccountRepository; import leets.weeth.domain.account.repository.ReceiptRepository; -import leets.weeth.domain.file.entity.File; import leets.weeth.domain.file.service.FileService; import leets.weeth.global.common.error.exception.custom.AccountNotFoundException; import leets.weeth.global.common.error.exception.custom.ReceiptNotFoundException; @@ -31,7 +30,7 @@ public void spend(ReceiptDTO.Spend dto, Integer cardinal, List fi Account account = accountRepository.findByCardinal(cardinal) .orElseThrow(AccountNotFoundException::new); - List images = fileService.uploadFiles(files); + List images = fileService.uploadFiles(files); Receipt receipt = mapper.from(dto, account, images); receiptRepository.save(receipt); diff --git a/src/main/java/leets/weeth/domain/event/entity/Event.java b/src/main/java/leets/weeth/domain/event/entity/Event.java index 59cf2f87..a31f7ce1 100644 --- a/src/main/java/leets/weeth/domain/event/entity/Event.java +++ b/src/main/java/leets/weeth/domain/event/entity/Event.java @@ -3,14 +3,13 @@ import jakarta.persistence.*; import leets.weeth.domain.event.dto.RequestEvent; import leets.weeth.domain.event.entity.enums.Type; -import leets.weeth.domain.file.entity.File; +import leets.weeth.domain.file.converter.FileListConverter; import leets.weeth.domain.notice.dto.RequestNotice; import leets.weeth.domain.user.entity.User; import leets.weeth.global.common.entity.BaseEntity; import lombok.*; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -48,8 +47,8 @@ public class Event extends BaseEntity { @Enumerated(EnumType.STRING) private Type type; - @OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true) - private List fileUrls = new ArrayList<>(); + @Convert(converter = FileListConverter.class) + private List files; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) @@ -67,12 +66,9 @@ public void updateFromEventDto(RequestEvent dto) { } // 공지 수정을 위한 메소드 - public void updateFromNoticeDto(RequestNotice dto, List fileUrlList) { + public void updateFromNoticeDto(RequestNotice dto, List files) { Optional.ofNullable(dto.title()).ifPresent(title -> this.title = title); Optional.ofNullable(dto.content()).ifPresent(content -> this.content = content); - Optional.ofNullable(fileUrlList).ifPresent(files -> { - this.fileUrls.clear(); - this.fileUrls.addAll(files); - }); + this.files = files; } } diff --git a/src/main/java/leets/weeth/domain/file/converter/FileListConverter.java b/src/main/java/leets/weeth/domain/file/converter/FileListConverter.java new file mode 100644 index 00000000..bf15dee2 --- /dev/null +++ b/src/main/java/leets/weeth/domain/file/converter/FileListConverter.java @@ -0,0 +1,35 @@ +package leets.weeth.domain.file.converter; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.persistence.AttributeConverter; + +import java.io.IOException; +import java.util.List; + +public class FileListConverter implements AttributeConverter, String> { + + private static final ObjectMapper mapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false); + + @Override + public String convertToDatabaseColumn(List attribute) { + try { + return mapper.writeValueAsString(attribute); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException(); + } + } + + @Override + public List convertToEntityAttribute(String dbData) { + try { + return mapper.readValue(dbData, new TypeReference<>() {}); + } catch (IOException e) { + throw new IllegalArgumentException(); + } + } +} diff --git a/src/main/java/leets/weeth/domain/file/entity/File.java b/src/main/java/leets/weeth/domain/file/entity/File.java deleted file mode 100644 index 9312f72a..00000000 --- a/src/main/java/leets/weeth/domain/file/entity/File.java +++ /dev/null @@ -1,24 +0,0 @@ -package leets.weeth.domain.file.entity; - -import jakarta.persistence.*; -import lombok.*; - -@AllArgsConstructor -@NoArgsConstructor -@ToString -@Entity -@Getter -public class File { - public File(String url) { - this.url = url; - } - - @Id //엔티티의 대푯값 지정 - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "file_id") - private Long id; - - private String url; - - -} diff --git a/src/main/java/leets/weeth/domain/file/repository/FileRepository.java b/src/main/java/leets/weeth/domain/file/repository/FileRepository.java deleted file mode 100644 index d3b91032..00000000 --- a/src/main/java/leets/weeth/domain/file/repository/FileRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package leets.weeth.domain.file.repository; - -import leets.weeth.domain.file.entity.File; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface FileRepository extends JpaRepository { - -} diff --git a/src/main/java/leets/weeth/domain/file/service/FileService.java b/src/main/java/leets/weeth/domain/file/service/FileService.java index 5485b12e..443cc7a6 100644 --- a/src/main/java/leets/weeth/domain/file/service/FileService.java +++ b/src/main/java/leets/weeth/domain/file/service/FileService.java @@ -2,17 +2,14 @@ import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.PutObjectRequest; -import leets.weeth.domain.file.repository.FileRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import leets.weeth.domain.file.entity.File; import java.io.FileOutputStream; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -21,37 +18,30 @@ @RequiredArgsConstructor public class FileService { - private final FileRepository fileRepository; - @Value("${cloud.aws.s3.bucket}") private String bucketName; private final AmazonS3 s3Client; - public List uploadFiles(List files) { + public List uploadFiles(List files) { // 다중 업로드 && 리스트 ","을 기준으로 하나의 문자열 반환 // files 갯수 0 이면 반환 "" if(files == null || files.isEmpty()) return List.of(); - List results = new ArrayList<>(); - - for (MultipartFile file : files) { - java.io.File fileObj = convertMultiPartFileToFile(file); - String originalFilename = file.getOriginalFilename(); - String extension = getFileExtension(originalFilename); - String fileName = UUID.randomUUID() + "." + extension; + return files.parallelStream() + .map(file -> { + java.io.File fileObj = convertMultiPartFileToFile(file); + String originalFilename = file.getOriginalFilename(); + String extension = getFileExtension(originalFilename); + String fileName = UUID.randomUUID() + "." + extension; - log.info("uploadFile fileName: {}", fileName); - s3Client.putObject(new PutObjectRequest(bucketName, fileName, fileObj)); - fileObj.delete(); - File newFile = new File(s3Client.getUrl(bucketName, fileName).toString()); + s3Client.putObject(new PutObjectRequest(bucketName, fileName, fileObj)); + fileObj.delete(); - - fileRepository.save(newFile); - results.add(newFile); - } - return results; + return s3Client.getUrl(bucketName, fileName).getPath(); + }) + .toList(); } private java.io.File convertMultiPartFileToFile(MultipartFile file) { diff --git a/src/main/java/leets/weeth/domain/notice/dto/ResponseNotice.java b/src/main/java/leets/weeth/domain/notice/dto/ResponseNotice.java index 21d4eb1f..c006c463 100644 --- a/src/main/java/leets/weeth/domain/notice/dto/ResponseNotice.java +++ b/src/main/java/leets/weeth/domain/notice/dto/ResponseNotice.java @@ -1,7 +1,6 @@ package leets.weeth.domain.notice.dto; import leets.weeth.domain.event.entity.enums.Type; -import leets.weeth.domain.file.entity.File; import lombok.Builder; import java.time.LocalDateTime; @@ -16,6 +15,6 @@ public record ResponseNotice( LocalDateTime modifiedAt, String userName, Type type, - List fileUrls + List fileUrls ) { } diff --git a/src/main/java/leets/weeth/domain/notice/mapper/NoticeMapper.java b/src/main/java/leets/weeth/domain/notice/mapper/NoticeMapper.java index 71b84c03..1fed69b8 100644 --- a/src/main/java/leets/weeth/domain/notice/mapper/NoticeMapper.java +++ b/src/main/java/leets/weeth/domain/notice/mapper/NoticeMapper.java @@ -1,7 +1,6 @@ package leets.weeth.domain.notice.mapper; import leets.weeth.domain.event.entity.Event; -import leets.weeth.domain.file.entity.File; import leets.weeth.domain.notice.dto.RequestNotice; import leets.weeth.domain.notice.dto.ResponseNotice; import leets.weeth.domain.user.entity.User; @@ -32,5 +31,5 @@ public interface NoticeMapper { @Mapping(target = "type", expression = "java( leets.weeth.domain.event.entity.enums.Type.NOTICE)"), @Mapping(target = "id", ignore = true) }) - Event fromNoticeDto(RequestNotice dto, List fileUrls, User user); + Event fromNoticeDto(RequestNotice dto, List files, User user); } diff --git a/src/main/java/leets/weeth/domain/notice/service/NoticeService.java b/src/main/java/leets/weeth/domain/notice/service/NoticeService.java index 017330ea..7bfe8a19 100644 --- a/src/main/java/leets/weeth/domain/notice/service/NoticeService.java +++ b/src/main/java/leets/weeth/domain/notice/service/NoticeService.java @@ -3,7 +3,6 @@ import leets.weeth.domain.event.entity.Event; import leets.weeth.domain.event.entity.enums.Type; import leets.weeth.domain.event.repository.EventRepository; -import leets.weeth.domain.file.entity.File; import leets.weeth.domain.file.service.FileService; import leets.weeth.domain.notice.dto.RequestNotice; import leets.weeth.domain.notice.dto.ResponseNotice; @@ -40,7 +39,7 @@ public void createNotice(RequestNotice requestNotice, List files, User user = userRepository.findById(userId) .orElseThrow(UserNotFoundException::new); - List fileUrls = fileService.uploadFiles(files); + List fileUrls = fileService.uploadFiles(files); eventRepository.save(noticeMapper.fromNoticeDto(requestNotice, fileUrls, user)); } @@ -76,9 +75,9 @@ public void updateNotice(Long noticeId, RequestNotice requestNotice, List fileUrls = fileService.uploadFiles(files); + List urls = fileService.uploadFiles(files); - oldNotice.updateFromNoticeDto(requestNotice, fileUrls); + oldNotice.updateFromNoticeDto(requestNotice, urls); } // 공지 삭제 diff --git a/src/main/java/leets/weeth/domain/post/dto/ResponsePostDTO.java b/src/main/java/leets/weeth/domain/post/dto/ResponsePostDTO.java index 335279f8..223743a0 100644 --- a/src/main/java/leets/weeth/domain/post/dto/ResponsePostDTO.java +++ b/src/main/java/leets/weeth/domain/post/dto/ResponsePostDTO.java @@ -1,9 +1,9 @@ package leets.weeth.domain.post.dto; import jakarta.validation.constraints.NotBlank; -import leets.weeth.domain.file.entity.File; import leets.weeth.domain.post.entity.Post; import lombok.*; + import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -24,7 +24,7 @@ public class ResponsePostDTO { private String content; @NotBlank private LocalDateTime time; - private List fileUrls; + private List fileUrls; private List comments; @NotBlank private Long commentCount; @@ -37,7 +37,7 @@ public static ResponsePostDTO createResponsePostDTO(Post post) { .title(post.getTitle()) .content(post.getContent()) .time(post.getTime()) - .fileUrls(post.getFileUrls()) + .fileUrls(post.getFiles()) .comments(post.getParentComments() .stream() .map(ResponseCommentDTO::createResponseCommentDto) diff --git a/src/main/java/leets/weeth/domain/post/entity/Post.java b/src/main/java/leets/weeth/domain/post/entity/Post.java index bf40dd80..82d4639b 100644 --- a/src/main/java/leets/weeth/domain/post/entity/Post.java +++ b/src/main/java/leets/weeth/domain/post/entity/Post.java @@ -3,11 +3,12 @@ import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; import jakarta.validation.constraints.NotEmpty; -import leets.weeth.domain.file.entity.File; +import leets.weeth.domain.file.converter.FileListConverter; import leets.weeth.domain.post.dto.RequestPostDTO; import leets.weeth.domain.user.entity.User; import leets.weeth.global.common.entity.BaseEntity; import lombok.*; + import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -41,25 +42,25 @@ public class Post extends BaseEntity { private List parentComments = new ArrayList<>(); LocalDateTime time; - @OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true) - private List fileUrls = new ArrayList<>(); - public static Post createPost(RequestPostDTO dto, User user, List urls){ + @Convert(converter = FileListConverter.class) + private List files = new ArrayList<>(); + + public static Post createPost(RequestPostDTO dto, User user, List files){ return Post.builder() .user(user) .title(dto.getTitle()) .content(dto.getContent()) .time(null) - .fileUrls(urls) + .files(files) .build(); } - public void updatePost(RequestPostDTO dto, List newUrls) { + public void updatePost(RequestPostDTO dto, List files) { this.title = dto.getTitle(); this.content = dto.getContent(); - this.fileUrls.clear(); // 기존 파일 제거 - this.fileUrls.addAll(newUrls); // 새로운 url 추가 + this.files = files; } public static Long calculateTotalComments(Post post) { diff --git a/src/main/java/leets/weeth/domain/post/service/PostService.java b/src/main/java/leets/weeth/domain/post/service/PostService.java index 9c6541f0..499d56bc 100644 --- a/src/main/java/leets/weeth/domain/post/service/PostService.java +++ b/src/main/java/leets/weeth/domain/post/service/PostService.java @@ -1,7 +1,6 @@ package leets.weeth.domain.post.service; import jakarta.transaction.Transactional; -import leets.weeth.domain.file.entity.File; import leets.weeth.domain.file.service.FileService; import leets.weeth.domain.post.dto.RequestPostDTO; import leets.weeth.domain.post.dto.ResponsePostDTO; @@ -19,6 +18,7 @@ import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; + import java.util.List; @RequiredArgsConstructor @@ -63,7 +63,7 @@ public void create(Long userId, RequestPostDTO requestPostDTO, List fileUrls; + List fileUrls; Post newPost; if(postId!=null){ Post targetPost = postRepository.findById(postId).orElse(null); diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 766b7b56..92773cc6 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -13,8 +13,8 @@ spring: ddl-auto: update servlet: multipart: - max-file-size: 5MB - max-request-size: 10MB + max-file-size: 30MB + max-request-size: 30MB resolve-lazily: true # MySQL 유저 생성 및 스키마 생성 터미널 명령어