From 3a1ab918125fa3098dce4789e3eff3910a25cad9 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 05:38:19 +0900 Subject: [PATCH 01/19] =?UTF-8?q?feat:=20User,=20Account=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../c4marathon/assignment/entity/Account.java | 67 +++++++++++++++++++ .../c4marathon/assignment/entity/User.java | 54 +++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 src/main/java/org/c4marathon/assignment/entity/Account.java create mode 100644 src/main/java/org/c4marathon/assignment/entity/User.java diff --git a/src/main/java/org/c4marathon/assignment/entity/Account.java b/src/main/java/org/c4marathon/assignment/entity/Account.java new file mode 100644 index 0000000..b54fe16 --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/entity/Account.java @@ -0,0 +1,67 @@ +package org.c4marathon.assignment.entity; + +import java.time.Instant; +import java.util.stream.IntStream; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.hibernate.annotations.ColumnDefault; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Entity +@Table(name = "account") +public class Account { + public static final String ACCOUNT_PREFIX = "3333"; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "account_id", nullable = false) + private Integer id; + + @Size(max = 13) + @NotNull + @Column(name = "account_number", nullable = false, length = 13) + private String accountNumber; + + @NotNull + @Column(name = "user_id", nullable = false) + private Integer userId; + + @NotNull + @Column(name = "account_type", nullable = false) + private Character accountType; + + @Size(max = 200) + @Column(name = "memo", length = 200) + private String memo; + + @NotNull + @ColumnDefault("0") + @Column(name = "balance", nullable = false) + private Long balance; + + @NotNull + @ColumnDefault("CURRENT_TIMESTAMP") + @Column(name = "create_date", nullable = false) + private Instant createDate; + + @Column(name = "recent_transaction_date") + private Instant recentTransactionDate; + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/org/c4marathon/assignment/entity/User.java b/src/main/java/org/c4marathon/assignment/entity/User.java new file mode 100644 index 0000000..09a5d7b --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/entity/User.java @@ -0,0 +1,54 @@ +package org.c4marathon.assignment.entity; + +import java.time.Instant; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Entity +@Table(name = "user") +public class User { + @Id + @Column(name = "user_id", nullable = false) + private Integer id; + + @Size(max = 30) + @NotNull + @Column(name = "username", nullable = false, length = 30) + private String username; + + @Size(max = 30) + @NotNull + @Column(name = "email", nullable = false, length = 30) + private String email; + + @Size(max = 10) + @NotNull + @Column(name = "nickname", nullable = false, length = 10) + private String nickname; + + @NotNull + @Column(name = "group_id", nullable = false) + private Integer groupId; + + @NotNull + @Column(name = "user_status", nullable = false) + private Character userStatus; + + @NotNull + @Column(name = "create_date", nullable = false) + private Instant createDate; + + @NotNull + @Column(name = "update_date", nullable = false) + private Instant updateDate; + +} \ No newline at end of file From fee398a6dc08170eeb1abfe09e565fb781e672fd Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 07:26:15 +0900 Subject: [PATCH 02/19] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/BadRequestException.java | 7 ++++++ .../handler/GlobalExceptionHandler.java | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/main/java/org/c4marathon/assignment/exception/BadRequestException.java create mode 100644 src/main/java/org/c4marathon/assignment/handler/GlobalExceptionHandler.java diff --git a/src/main/java/org/c4marathon/assignment/exception/BadRequestException.java b/src/main/java/org/c4marathon/assignment/exception/BadRequestException.java new file mode 100644 index 0000000..2d41cac --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/exception/BadRequestException.java @@ -0,0 +1,7 @@ +package org.c4marathon.assignment.exception; + +public class BadRequestException extends RuntimeException { + public BadRequestException(String message) { + super(message); + } +} diff --git a/src/main/java/org/c4marathon/assignment/handler/GlobalExceptionHandler.java b/src/main/java/org/c4marathon/assignment/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..267f62d --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/handler/GlobalExceptionHandler.java @@ -0,0 +1,24 @@ +package org.c4marathon.assignment.handler; + +import java.util.HashMap; +import java.util.Map; + +import org.c4marathon.assignment.exception.BadRequestException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class GlobalExceptionHandler { + private static final String MESSAGE = "message"; + + @ExceptionHandler(BadRequestException.class) + public ResponseEntity> handleBadRequestException(BadRequestException ex) { + Map resultMap = new HashMap<>(); + + resultMap.put(MESSAGE, ex.getMessage()); + + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resultMap); + } +} \ No newline at end of file From 4e20539fec36b6d2021d6cade212d8b260020828 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 07:27:08 +0900 Subject: [PATCH 03/19] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/UserJpaRepository.java | 10 ++++++++++ .../assignment/repository/UserRepository.java | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/main/java/org/c4marathon/assignment/repository/UserJpaRepository.java create mode 100644 src/main/java/org/c4marathon/assignment/repository/UserRepository.java diff --git a/src/main/java/org/c4marathon/assignment/repository/UserJpaRepository.java b/src/main/java/org/c4marathon/assignment/repository/UserJpaRepository.java new file mode 100644 index 0000000..0a5aa58 --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/repository/UserJpaRepository.java @@ -0,0 +1,10 @@ +package org.c4marathon.assignment.repository; + +import java.util.Optional; + +import org.c4marathon.assignment.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserJpaRepository extends JpaRepository { + Optional findByEmail(String email); +} \ No newline at end of file diff --git a/src/main/java/org/c4marathon/assignment/repository/UserRepository.java b/src/main/java/org/c4marathon/assignment/repository/UserRepository.java new file mode 100644 index 0000000..715f205 --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/repository/UserRepository.java @@ -0,0 +1,18 @@ +package org.c4marathon.assignment.repository; + +import java.util.Optional; + +import org.c4marathon.assignment.entity.User; +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; + +@Repository +@RequiredArgsConstructor +public class UserRepository { + private final UserJpaRepository userJpaRepository; + + public Optional findUserByEmail(String email) { + return userJpaRepository.findByEmail(email); + } +} From ff1a7b39380c398f393f83bfe3aae20b36f99b99 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 22:18:28 +0900 Subject: [PATCH 04/19] =?UTF-8?q?feat:=20=EA=B1=B0=EB=9E=98=20=EB=82=B4?= =?UTF-8?q?=EC=97=AD=20=EC=9D=91=EB=8B=B5=20dto=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/TransactionRes.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/main/java/org/c4marathon/assignment/dto/response/TransactionRes.java diff --git a/src/main/java/org/c4marathon/assignment/dto/response/TransactionRes.java b/src/main/java/org/c4marathon/assignment/dto/response/TransactionRes.java new file mode 100644 index 0000000..0074b46 --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/dto/response/TransactionRes.java @@ -0,0 +1,31 @@ +package org.c4marathon.assignment.dto.response; + +import java.time.Instant; + +import org.c4marathon.assignment.entity.Transaction; + +public record TransactionRes( + String senderAccount, + String receiverAccount, + String senderSwiftCode, + String receiverSwiftCode, + String senderName, + String receiverName, + Long amount, + String memo, + Instant transactionDate +) { + public TransactionRes(Transaction transaction) { + this( + transaction.getSenderAccount(), + transaction.getReceiverAccount(), + transaction.getSenderSwiftCode(), + transaction.getReceiverSwiftCode(), + transaction.getSenderName(), + transaction.getReceiverName(), + transaction.getAmount(), + transaction.getMemo(), + transaction.getTransactionDate() + ); + } +} From 3fe6259ad759477ef9e9f3a673542258cd8a2ba9 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 22:18:55 +0900 Subject: [PATCH 05/19] =?UTF-8?q?feat:=20=EA=B3=84=EC=A2=8C=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=9D=91=EB=8B=B5=20dto=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/dto/response/AccountRes.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/org/c4marathon/assignment/dto/response/AccountRes.java diff --git a/src/main/java/org/c4marathon/assignment/dto/response/AccountRes.java b/src/main/java/org/c4marathon/assignment/dto/response/AccountRes.java new file mode 100644 index 0000000..3eab91b --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/dto/response/AccountRes.java @@ -0,0 +1,15 @@ +package org.c4marathon.assignment.dto.response; + +import org.c4marathon.assignment.entity.Account; + +public record AccountRes( + String accountNumber, + Long balance +) { + public AccountRes(Account account) { + this( + account.getAccountNumber(), + account.getBalance() + ); + } +} \ No newline at end of file From 77bc6466e377c907b44ea1602e41db5b127a5dd4 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 22:19:42 +0900 Subject: [PATCH 06/19] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EA=B8=88=EC=9C=B5=20=ED=99=9C=EB=8F=99=20=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?dto=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/FinancialInfoRes.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/org/c4marathon/assignment/dto/response/FinancialInfoRes.java diff --git a/src/main/java/org/c4marathon/assignment/dto/response/FinancialInfoRes.java b/src/main/java/org/c4marathon/assignment/dto/response/FinancialInfoRes.java new file mode 100644 index 0000000..eff909a --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/dto/response/FinancialInfoRes.java @@ -0,0 +1,19 @@ +package org.c4marathon.assignment.dto.response; + +import java.util.List; + +public record FinancialInfoRes( + List accountRes, + List transactionRes, + int accountTotal, + int transactionTotal +) { + public FinancialInfoRes(List accountRes, List transactionRes) { + this( + accountRes, + transactionRes, + accountRes.size(), + transactionRes.size() + ); + } +} \ No newline at end of file From 0e6c9091dde298b26de0b281c32bff4f7be68c09 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 22:23:09 +0900 Subject: [PATCH 07/19] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EB=AA=A8=EB=93=A0=20=EA=B3=84=EC=A2=8C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 한 사용자의 계좌가 1000개를 넘지 않을 것이라 생각해 데이터를 한번에 가져오도록 구현했습니다. --- .../repository/AccountJpaRepository.java | 12 ++++++++++++ .../repository/AccountRepository.java | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/main/java/org/c4marathon/assignment/repository/AccountJpaRepository.java create mode 100644 src/main/java/org/c4marathon/assignment/repository/AccountRepository.java diff --git a/src/main/java/org/c4marathon/assignment/repository/AccountJpaRepository.java b/src/main/java/org/c4marathon/assignment/repository/AccountJpaRepository.java new file mode 100644 index 0000000..2b62e20 --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/repository/AccountJpaRepository.java @@ -0,0 +1,12 @@ +package org.c4marathon.assignment.repository; + +import java.util.List; + +import org.c4marathon.assignment.entity.Account; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AccountJpaRepository extends JpaRepository { + List findAllByUserId(Integer userId); +} diff --git a/src/main/java/org/c4marathon/assignment/repository/AccountRepository.java b/src/main/java/org/c4marathon/assignment/repository/AccountRepository.java new file mode 100644 index 0000000..05dc073 --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/repository/AccountRepository.java @@ -0,0 +1,18 @@ +package org.c4marathon.assignment.repository; + +import java.util.List; + +import org.c4marathon.assignment.entity.Account; +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; + +@Repository +@RequiredArgsConstructor +public class AccountRepository { + private final AccountJpaRepository accountJpaRepository; + + public List findAllAccountByUserId(Integer userId) { + return accountJpaRepository.findAllByUserId(userId); + } +} From 318e0033cc9ad7c0b415c41e0e71c53a7806a3df Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 22:27:31 +0900 Subject: [PATCH 08/19] =?UTF-8?q?feat:=20=ED=95=9C=EB=B2=88=EC=97=90=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=ED=8A=B8=EB=9E=9C=EC=9E=AD=EC=85=98=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/repository/TransactionJpaRepository.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/c4marathon/assignment/repository/TransactionJpaRepository.java b/src/main/java/org/c4marathon/assignment/repository/TransactionJpaRepository.java index 6854083..4c7e58a 100644 --- a/src/main/java/org/c4marathon/assignment/repository/TransactionJpaRepository.java +++ b/src/main/java/org/c4marathon/assignment/repository/TransactionJpaRepository.java @@ -1,6 +1,7 @@ package org.c4marathon.assignment.repository; import java.time.Instant; +import java.util.List; import org.c4marathon.assignment.entity.Transaction; import org.springframework.data.jpa.repository.JpaRepository; @@ -23,4 +24,11 @@ SELECT MAX(t.id) ) """) Long cumulativeRemittanceBeforeDate(@Param("date") Instant date); + + @Query(""" + SELECT t + FROM Transaction t WHERE t.senderAccount = :account + OR t.receiverAccount = :account + """) + List findAllTransaction(@Param("account") String account); } From 5f16c8de500f11814e2521a482703b6493c389d5 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 22:31:42 +0900 Subject: [PATCH 09/19] =?UTF-8?q?feat:=20=ED=95=9C=EB=B2=88=EC=97=90=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=ED=8A=B8=EB=9E=9C=EC=9E=AD=EC=85=98=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/repository/TransactionRepository.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/c4marathon/assignment/repository/TransactionRepository.java b/src/main/java/org/c4marathon/assignment/repository/TransactionRepository.java index c094d24..fdf3099 100644 --- a/src/main/java/org/c4marathon/assignment/repository/TransactionRepository.java +++ b/src/main/java/org/c4marathon/assignment/repository/TransactionRepository.java @@ -1,7 +1,9 @@ package org.c4marathon.assignment.repository; import java.time.Instant; +import java.util.List; +import org.c4marathon.assignment.entity.Transaction; import org.springframework.stereotype.Repository; import lombok.RequiredArgsConstructor; @@ -18,4 +20,8 @@ public Long sumAmountBetweenDate(Instant startInstantDate, Instant endInstantDat public Long cumulativeRemittanceBeforeDate(Instant instantDate) { return transactionJpaRepository.cumulativeRemittanceBeforeDate(instantDate); } + + public List findAllTransaction(String account) { + return transactionJpaRepository.findAllTransaction(account); + } } From 686c9fde9874c96a9c77100a6741e5fe04fa4d53 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 22:38:50 +0900 Subject: [PATCH 10/19] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EB=AA=A8=EB=93=A0=20=EA=B3=84=EC=A2=8C=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EC=99=80=20=EB=AA=A8=EB=93=A0=20=EA=B1=B0=EB=9E=98=20?= =?UTF-8?q?=EB=82=B4=EC=97=AD=EC=9D=84=20=EC=A0=9C=EA=B3=B5=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 각 계좌마다 연관된 거래 내역을 가져오는 과정에서 병목이 있었습니다. - A라는 계좌와 연관된 거래 내역을 모두 가져오기까지 기다리는 것이 아니라 동시에 각 계좌와 연관된 거래 내역을 모두 가져오게끔 했습니다. - CompletableFutre를 이용하여 각 계좌마다 연관된 거래 내역을 가져오는 과정을 비동기적으로 구현하였습니다. --- .../controller/MarathonController.java | 22 ++++++++ .../assignment/service/MarathonService.java | 52 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/main/java/org/c4marathon/assignment/controller/MarathonController.java create mode 100644 src/main/java/org/c4marathon/assignment/service/MarathonService.java diff --git a/src/main/java/org/c4marathon/assignment/controller/MarathonController.java b/src/main/java/org/c4marathon/assignment/controller/MarathonController.java new file mode 100644 index 0000000..f117152 --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/controller/MarathonController.java @@ -0,0 +1,22 @@ +package org.c4marathon.assignment.controller; + +import org.c4marathon.assignment.dto.response.FinancialInfoRes; +import org.c4marathon.assignment.service.MarathonService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/marathon") +@RequiredArgsConstructor +public class MarathonController { + private final MarathonService marathonService; + + @GetMapping("/all-info") + public FinancialInfoRes getAllInfo(@RequestParam String email) { + return marathonService.getAllInfo(email); + } +} diff --git a/src/main/java/org/c4marathon/assignment/service/MarathonService.java b/src/main/java/org/c4marathon/assignment/service/MarathonService.java new file mode 100644 index 0000000..ec35524 --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/service/MarathonService.java @@ -0,0 +1,52 @@ +package org.c4marathon.assignment.service; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +import org.c4marathon.assignment.dto.response.AccountRes; +import org.c4marathon.assignment.dto.response.FinancialInfoRes; +import org.c4marathon.assignment.dto.response.TransactionRes; +import org.c4marathon.assignment.entity.User; +import org.c4marathon.assignment.exception.BadRequestException; +import org.c4marathon.assignment.repository.AccountRepository; +import org.c4marathon.assignment.repository.TransactionRepository; +import org.c4marathon.assignment.repository.UserRepository; +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class MarathonService { + private final UserRepository userRepository; + private final AccountRepository accountRepository; + private final Executor asyncTaskExecutor; + private final TransactionRepository transactionRepository; + + public FinancialInfoRes getAllInfo(String email) { + User user = userRepository.findUserByEmail(email) + .orElseThrow(() -> new BadRequestException("존재하지 않는 회원입니다.")); + + List accountResList = accountRepository.findAllAccountByUserId(user.getId()) + .stream().map(AccountRes::new).toList(); + + List>> futures = accountResList.stream() + .map(accountRes -> CompletableFuture.supplyAsync(() -> + transactionRepository.findAllTransaction(accountRes.accountNumber()) + .stream() + .map(TransactionRes::new) + .toList(), + asyncTaskExecutor)) + .toList(); + + List transactions = futures.stream() + .map(CompletableFuture::join) + .filter(Objects::nonNull) + .flatMap(List::stream) + .toList(); + + return new FinancialInfoRes(accountResList, transactions); + } +} From 8687e85e8ab85027343d4279dc1729774e563de9 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 23:26:44 +0900 Subject: [PATCH 11/19] =?UTF-8?q?feat:=20=ED=95=A8=EC=88=98=ED=98=95=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=EA=B7=B8=EB=9E=98=EB=B0=8D=20=ED=85=9C?= =?UTF-8?q?=ED=94=8C=EB=A6=BF=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/C4QueryExecuteTemplate.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/org/c4marathon/assignment/util/C4QueryExecuteTemplate.java diff --git a/src/main/java/org/c4marathon/assignment/util/C4QueryExecuteTemplate.java b/src/main/java/org/c4marathon/assignment/util/C4QueryExecuteTemplate.java new file mode 100644 index 0000000..81d2f52 --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/util/C4QueryExecuteTemplate.java @@ -0,0 +1,26 @@ +package org.c4marathon.assignment.util; + +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; + +public class C4QueryExecuteTemplate { + /** + * Cursor Paging 을 적용하여 Select 를 수행한 후, 조회된 결과로 비즈니스 로직을 수행한다. + * @param limit + * @param selectFunction + * @param resultConsumer + * @param + */ + public static void selectAndExecuteWithCursor(int limit, Function> selectFunction, + Consumer> resultConsumer) { + List resultList = null; + do { + resultList = selectFunction.apply(resultList != null ? resultList.get(resultList.size() - 1) : null); + + if (!resultList.isEmpty()) { + resultConsumer.accept(resultList); + } + } while (resultList.size() >= limit); + } +} From e715125641982b85be96c691d50e5e8b4b88d6d7 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Thu, 14 Nov 2024 23:28:31 +0900 Subject: [PATCH 12/19] =?UTF-8?q?feat:=20limit=20=EB=A7=8C=ED=81=BC=20?= =?UTF-8?q?=ED=8A=B8=EB=9E=9C=EC=9E=AD=EC=85=98=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/TransactionJpaRepository.java | 22 +++++++++++++++++++ .../repository/TransactionRepository.java | 10 +++++++++ 2 files changed, 32 insertions(+) diff --git a/src/main/java/org/c4marathon/assignment/repository/TransactionJpaRepository.java b/src/main/java/org/c4marathon/assignment/repository/TransactionJpaRepository.java index 4c7e58a..2bac5a3 100644 --- a/src/main/java/org/c4marathon/assignment/repository/TransactionJpaRepository.java +++ b/src/main/java/org/c4marathon/assignment/repository/TransactionJpaRepository.java @@ -31,4 +31,26 @@ SELECT MAX(t.id) OR t.receiverAccount = :account """) List findAllTransaction(@Param("account") String account); + + @Query(""" + SELECT t + FROM Transaction t + WHERE (t.receiverAccount = :account OR t.senderAccount = :account) + AND t.id > :lastId + ORDER BY t.id + LIMIT :limit + """) + List findTransactionByAccountNumberAndLastTransactionId(@Param("account") String accountNumber, + @Param("lastId") Integer lastTransactionId, + @Param("limit") int limit); + + @Query(""" + SELECT t + FROM Transaction t + WHERE t.receiverAccount = :account OR t.senderAccount = :account + ORDER BY t.id + LIMIT :limit + """) + List findTransaction(@Param("account") String accountNumber, + @Param("limit") int limit); } diff --git a/src/main/java/org/c4marathon/assignment/repository/TransactionRepository.java b/src/main/java/org/c4marathon/assignment/repository/TransactionRepository.java index fdf3099..7ba01e3 100644 --- a/src/main/java/org/c4marathon/assignment/repository/TransactionRepository.java +++ b/src/main/java/org/c4marathon/assignment/repository/TransactionRepository.java @@ -24,4 +24,14 @@ public Long cumulativeRemittanceBeforeDate(Instant instantDate) { public List findAllTransaction(String account) { return transactionJpaRepository.findAllTransaction(account); } + + public List findTransactionByAccountNumberAndLastTransactionId(String accountNumber, + Integer lastTransactionId, int limit) { + if (lastTransactionId == null) { + return transactionJpaRepository.findTransaction(accountNumber, limit); + } + + return transactionJpaRepository.findTransactionByAccountNumberAndLastTransactionId(accountNumber, + lastTransactionId, limit); + } } From 8d640f8807be66b1aafe9b5051fcc90765de1400 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Fri, 15 Nov 2024 01:48:03 +0900 Subject: [PATCH 13/19] =?UTF-8?q?feat:=20limit=EB=A7=8C=ED=81=BC=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=EC=9D=98=20=EB=AA=A8=EB=93=A0=20?= =?UTF-8?q?=EA=B3=84=EC=A2=8C=20=EC=A0=95=EB=B3=B4=EC=99=80=20=EB=AA=A8?= =?UTF-8?q?=EB=93=A0=20=EA=B1=B0=EB=9E=98=20=EB=82=B4=EC=97=AD=EC=9D=84=20?= =?UTF-8?q?=EC=A0=9C=EA=B3=B5=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 각 계좌마다 연관된 거래 내역을 가져오는 과정에서 병목이 있었습니다. - A라는 계좌와 연관된 거래 내역을 모두 가져오기까지 기다리는 것이 아니라 동시에 각 계좌와 연관된 거래 내역을 모두 가져오게끔 했습니다. - CompletableFutre를 이용하여 각 계좌마다 연관된 거래 내역을 가져오는 과정을 비동기적으로 구현하였습니다. - 트랜잭션 개수가 증가할 때를 대비하여 매번 limit만큼 조회해오도록 수정했습니다. - 현재 특정 계좌와 연관된 트랜잭션의 최대 개수가 1000을 넘어가는 경우가 있기 때문에 limit 크기는 1000으로 고정했습니다. --- .../controller/MarathonController.java | 4 +-- .../assignment/service/MarathonService.java | 25 +++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/c4marathon/assignment/controller/MarathonController.java b/src/main/java/org/c4marathon/assignment/controller/MarathonController.java index f117152..ba7e245 100644 --- a/src/main/java/org/c4marathon/assignment/controller/MarathonController.java +++ b/src/main/java/org/c4marathon/assignment/controller/MarathonController.java @@ -16,7 +16,7 @@ public class MarathonController { private final MarathonService marathonService; @GetMapping("/all-info") - public FinancialInfoRes getAllInfo(@RequestParam String email) { - return marathonService.getAllInfo(email); + public FinancialInfoRes getAllInfoWithLimit(@RequestParam String email) { + return marathonService.getAllInfoWithLimit(email); } } diff --git a/src/main/java/org/c4marathon/assignment/service/MarathonService.java b/src/main/java/org/c4marathon/assignment/service/MarathonService.java index ec35524..4c0b725 100644 --- a/src/main/java/org/c4marathon/assignment/service/MarathonService.java +++ b/src/main/java/org/c4marathon/assignment/service/MarathonService.java @@ -1,5 +1,6 @@ package org.c4marathon.assignment.service; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; @@ -8,11 +9,13 @@ import org.c4marathon.assignment.dto.response.AccountRes; import org.c4marathon.assignment.dto.response.FinancialInfoRes; import org.c4marathon.assignment.dto.response.TransactionRes; +import org.c4marathon.assignment.entity.Transaction; import org.c4marathon.assignment.entity.User; import org.c4marathon.assignment.exception.BadRequestException; import org.c4marathon.assignment.repository.AccountRepository; import org.c4marathon.assignment.repository.TransactionRepository; import org.c4marathon.assignment.repository.UserRepository; +import org.c4marathon.assignment.util.C4QueryExecuteTemplate; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; @@ -20,12 +23,13 @@ @Service @RequiredArgsConstructor public class MarathonService { + public static final int LIMIT_SIZE = 1000; private final UserRepository userRepository; private final AccountRepository accountRepository; private final Executor asyncTaskExecutor; private final TransactionRepository transactionRepository; - public FinancialInfoRes getAllInfo(String email) { + public FinancialInfoRes getAllInfoWithLimit(String email) { User user = userRepository.findUserByEmail(email) .orElseThrow(() -> new BadRequestException("존재하지 않는 회원입니다.")); @@ -33,12 +37,19 @@ public FinancialInfoRes getAllInfo(String email) { .stream().map(AccountRes::new).toList(); List>> futures = accountResList.stream() - .map(accountRes -> CompletableFuture.supplyAsync(() -> - transactionRepository.findAllTransaction(accountRes.accountNumber()) - .stream() - .map(TransactionRes::new) - .toList(), - asyncTaskExecutor)) + .map(accountRes -> CompletableFuture.supplyAsync(() -> { + List transactionResList = new ArrayList<>(); + + C4QueryExecuteTemplate.selectAndExecuteWithCursor(LIMIT_SIZE, + lastTransaction -> transactionRepository.findTransactionByAccountNumberAndLastTransactionId( + accountRes.accountNumber(), lastTransaction == null ? null : lastTransaction.getId(), + LIMIT_SIZE), + transactions -> transactionResList.addAll( + transactions.stream().map(TransactionRes::new).toList()) + ); + + return transactionResList; + }, asyncTaskExecutor)) .toList(); List transactions = futures.stream() From 3f551070a4f947de185d0d78fb1c5876343ec551 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Fri, 15 Nov 2024 20:33:30 +0900 Subject: [PATCH 14/19] =?UTF-8?q?feat:=20=EC=95=88=EC=A0=95=EC=A0=81?= =?UTF-8?q?=EC=9D=B8=20thread=20=EC=82=AC=EC=9A=A9=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=BB=A4=EC=8A=A4=ED=85=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 CompletableFuture를 사용한 상태에서 locust를 이용해 성능 테스트 한 결과 ConnectionException 발생으로 임시 수정 --- .../assignment/core/C4ThreadPoolExecutor.java | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/main/java/org/c4marathon/assignment/core/C4ThreadPoolExecutor.java diff --git a/src/main/java/org/c4marathon/assignment/core/C4ThreadPoolExecutor.java b/src/main/java/org/c4marathon/assignment/core/C4ThreadPoolExecutor.java new file mode 100644 index 0000000..efddba8 --- /dev/null +++ b/src/main/java/org/c4marathon/assignment/core/C4ThreadPoolExecutor.java @@ -0,0 +1,78 @@ +package org.c4marathon.assignment.core; + +import java.util.concurrent.Executor; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@RequiredArgsConstructor +@Slf4j +public class C4ThreadPoolExecutor implements Executor { + private final int threadCount; + private final int queueSize; + private ThreadPoolExecutor threadPoolExecutor; + private RuntimeException exception = null; + + public void init() { + if (threadPoolExecutor != null) { + return; + } + + threadPoolExecutor = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue<>(queueSize), + (r, executor) -> { + try { + executor.getQueue().put(r); + } catch (InterruptedException e) { + log.error(e.toString(), e); + Thread.currentThread().interrupt(); + } + }); + } + + @Override + public void execute(Runnable command) { + if (isInvalidState()) { + return; + } + + threadPoolExecutor.execute(() -> { + try { + command.run(); + } catch (RuntimeException e) { + log.error(e.toString(), e); + exception = e; + } + }); + } + + public void waitToEnd() { + if (isInvalidState()) { + return; + } + + threadPoolExecutor.shutdown(); + while (true) { + try { + if (threadPoolExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS)) { + break; + } + } catch (InterruptedException e) { + log.error(e.toString(), e); + Thread.currentThread().interrupt(); + } + } + + threadPoolExecutor = null; + if (exception != null) { + throw exception; + } + } + + private boolean isInvalidState() { + return threadPoolExecutor == null || threadPoolExecutor.isTerminating() || threadPoolExecutor.isTerminated(); + } +} \ No newline at end of file From 78e6dd37bd2b1452b540f98a45c6e28567c1b9d5 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Fri, 15 Nov 2024 20:34:13 +0900 Subject: [PATCH 15/19] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20thr?= =?UTF-8?q?ead=20=EC=82=AC=EC=9A=A9=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/service/MarathonService.java | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/c4marathon/assignment/service/MarathonService.java b/src/main/java/org/c4marathon/assignment/service/MarathonService.java index 4c0b725..04f9cbf 100644 --- a/src/main/java/org/c4marathon/assignment/service/MarathonService.java +++ b/src/main/java/org/c4marathon/assignment/service/MarathonService.java @@ -6,6 +6,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import org.c4marathon.assignment.core.C4ThreadPoolExecutor; import org.c4marathon.assignment.dto.response.AccountRes; import org.c4marathon.assignment.dto.response.FinancialInfoRes; import org.c4marathon.assignment.dto.response.TransactionRes; @@ -24,10 +25,13 @@ @RequiredArgsConstructor public class MarathonService { public static final int LIMIT_SIZE = 1000; + public static final int CORE_POOL_SIZE = 8; + public static final int MAX_POOL_SIZE = 32; private final UserRepository userRepository; private final AccountRepository accountRepository; private final Executor asyncTaskExecutor; private final TransactionRepository transactionRepository; + private final C4ThreadPoolExecutor threadPoolExecutor = new C4ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE); public FinancialInfoRes getAllInfoWithLimit(String email) { User user = userRepository.findUserByEmail(email) @@ -36,28 +40,22 @@ public FinancialInfoRes getAllInfoWithLimit(String email) { List accountResList = accountRepository.findAllAccountByUserId(user.getId()) .stream().map(AccountRes::new).toList(); - List>> futures = accountResList.stream() - .map(accountRes -> CompletableFuture.supplyAsync(() -> { - List transactionResList = new ArrayList<>(); - - C4QueryExecuteTemplate.selectAndExecuteWithCursor(LIMIT_SIZE, - lastTransaction -> transactionRepository.findTransactionByAccountNumberAndLastTransactionId( - accountRes.accountNumber(), lastTransaction == null ? null : lastTransaction.getId(), - LIMIT_SIZE), - transactions -> transactionResList.addAll( - transactions.stream().map(TransactionRes::new).toList()) - ); - - return transactionResList; - }, asyncTaskExecutor)) - .toList(); - - List transactions = futures.stream() - .map(CompletableFuture::join) - .filter(Objects::nonNull) - .flatMap(List::stream) - .toList(); - - return new FinancialInfoRes(accountResList, transactions); + List transactionResList = new ArrayList<>(); + + threadPoolExecutor.init(); + + accountResList.forEach(accountRes -> threadPoolExecutor.execute(() -> { + C4QueryExecuteTemplate.selectAndExecuteWithCursor(LIMIT_SIZE, + lastTransaction -> transactionRepository.findTransactionByAccountNumberAndLastTransactionId( + accountRes.accountNumber(), lastTransaction == null ? null : lastTransaction.getId(), + LIMIT_SIZE), + transactions -> transactionResList.addAll( + transactions.stream().map(TransactionRes::new).toList()) + ); + })); + + threadPoolExecutor.waitToEnd(); + + return new FinancialInfoRes(accountResList, transactionResList); } } From f6570733c2f9f823962284f3f805fc200e42c927 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Fri, 15 Nov 2024 20:35:18 +0900 Subject: [PATCH 16/19] =?UTF-8?q?refactor:=20=EB=AF=B8=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/c4marathon/assignment/service/MarathonService.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/org/c4marathon/assignment/service/MarathonService.java b/src/main/java/org/c4marathon/assignment/service/MarathonService.java index 04f9cbf..34b7eae 100644 --- a/src/main/java/org/c4marathon/assignment/service/MarathonService.java +++ b/src/main/java/org/c4marathon/assignment/service/MarathonService.java @@ -2,8 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import org.c4marathon.assignment.core.C4ThreadPoolExecutor; @@ -29,7 +27,6 @@ public class MarathonService { public static final int MAX_POOL_SIZE = 32; private final UserRepository userRepository; private final AccountRepository accountRepository; - private final Executor asyncTaskExecutor; private final TransactionRepository transactionRepository; private final C4ThreadPoolExecutor threadPoolExecutor = new C4ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE); From f23c4d79c41917bf384ce19e236d7c3deb6d83af Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Fri, 15 Nov 2024 23:10:11 +0900 Subject: [PATCH 17/19] =?UTF-8?q?feat:=20=EB=B9=84=EA=B5=90=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20=EB=B3=91=EB=A0=AC=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=95=88=ED=95=98=EB=8A=94=20api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MarathonController.java | 5 ++++ .../assignment/service/MarathonService.java | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/main/java/org/c4marathon/assignment/controller/MarathonController.java b/src/main/java/org/c4marathon/assignment/controller/MarathonController.java index ba7e245..85b42a5 100644 --- a/src/main/java/org/c4marathon/assignment/controller/MarathonController.java +++ b/src/main/java/org/c4marathon/assignment/controller/MarathonController.java @@ -19,4 +19,9 @@ public class MarathonController { public FinancialInfoRes getAllInfoWithLimit(@RequestParam String email) { return marathonService.getAllInfoWithLimit(email); } + + @GetMapping("/all-info-not-parallel") + public FinancialInfoRes getAllInfoNotParallel(@RequestParam String email) { + return marathonService.getAllInfoNotParallel(email); + } } diff --git a/src/main/java/org/c4marathon/assignment/service/MarathonService.java b/src/main/java/org/c4marathon/assignment/service/MarathonService.java index 34b7eae..af54606 100644 --- a/src/main/java/org/c4marathon/assignment/service/MarathonService.java +++ b/src/main/java/org/c4marathon/assignment/service/MarathonService.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.concurrent.Executor; import org.c4marathon.assignment.core.C4ThreadPoolExecutor; @@ -55,4 +56,33 @@ public FinancialInfoRes getAllInfoWithLimit(String email) { return new FinancialInfoRes(accountResList, transactionResList); } + + public FinancialInfoRes getAllInfoNotParallel(String email) { + User user = userRepository.findUserByEmail(email) + .orElseThrow(() -> new BadRequestException("존재하지 않는 회원입니다.")); + + List accountResList = accountRepository.findAllAccountByUserId(user.getId()) + .stream().map(AccountRes::new).toList(); + + List> transactionRes = accountResList.stream() + .map(accountRes -> { + List transactionResList = new ArrayList<>(); + + C4QueryExecuteTemplate.selectAndExecuteWithCursor(LIMIT_SIZE, + lastTransaction -> transactionRepository.findTransactionByAccountNumberAndLastTransactionId( + accountRes.accountNumber(), lastTransaction == null ? null : lastTransaction.getId(), + LIMIT_SIZE), + transactions -> transactionResList.addAll( + transactions.stream().map(TransactionRes::new).toList()) + ); + return transactionResList; + }) + .toList(); + + List transactions = transactionRes.stream() + .flatMap(List::stream) + .toList(); + + return new FinancialInfoRes(accountResList, transactions); + } } From 1ae25816bbc34f0bec9a2b657df43111e61102b7 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Fri, 15 Nov 2024 23:15:40 +0900 Subject: [PATCH 18/19] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EB=94=94=EB=A5=BC=20=ED=86=B5=ED=95=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 랜덤 유저 아이디를 통해 성능테스트를 진행하고자 변경했습니다. --- .../assignment/controller/MarathonController.java | 8 ++++---- .../assignment/repository/UserJpaRepository.java | 2 +- .../c4marathon/assignment/repository/UserRepository.java | 4 ++-- .../c4marathon/assignment/service/MarathonService.java | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/c4marathon/assignment/controller/MarathonController.java b/src/main/java/org/c4marathon/assignment/controller/MarathonController.java index 85b42a5..9bd63a7 100644 --- a/src/main/java/org/c4marathon/assignment/controller/MarathonController.java +++ b/src/main/java/org/c4marathon/assignment/controller/MarathonController.java @@ -16,12 +16,12 @@ public class MarathonController { private final MarathonService marathonService; @GetMapping("/all-info") - public FinancialInfoRes getAllInfoWithLimit(@RequestParam String email) { - return marathonService.getAllInfoWithLimit(email); + public FinancialInfoRes getAllInfoWithLimit(@RequestParam Integer id) { + return marathonService.getAllInfoWithLimit(id); } @GetMapping("/all-info-not-parallel") - public FinancialInfoRes getAllInfoNotParallel(@RequestParam String email) { - return marathonService.getAllInfoNotParallel(email); + public FinancialInfoRes getAllInfoNotParallel(@RequestParam Integer id) { + return marathonService.getAllInfoNotParallel(id); } } diff --git a/src/main/java/org/c4marathon/assignment/repository/UserJpaRepository.java b/src/main/java/org/c4marathon/assignment/repository/UserJpaRepository.java index 0a5aa58..2f267cf 100644 --- a/src/main/java/org/c4marathon/assignment/repository/UserJpaRepository.java +++ b/src/main/java/org/c4marathon/assignment/repository/UserJpaRepository.java @@ -6,5 +6,5 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface UserJpaRepository extends JpaRepository { - Optional findByEmail(String email); + Optional findById(Integer id); } \ No newline at end of file diff --git a/src/main/java/org/c4marathon/assignment/repository/UserRepository.java b/src/main/java/org/c4marathon/assignment/repository/UserRepository.java index 715f205..c0dedbb 100644 --- a/src/main/java/org/c4marathon/assignment/repository/UserRepository.java +++ b/src/main/java/org/c4marathon/assignment/repository/UserRepository.java @@ -12,7 +12,7 @@ public class UserRepository { private final UserJpaRepository userJpaRepository; - public Optional findUserByEmail(String email) { - return userJpaRepository.findByEmail(email); + public Optional findUserById(Integer id) { + return userJpaRepository.findById(id); } } diff --git a/src/main/java/org/c4marathon/assignment/service/MarathonService.java b/src/main/java/org/c4marathon/assignment/service/MarathonService.java index af54606..0134360 100644 --- a/src/main/java/org/c4marathon/assignment/service/MarathonService.java +++ b/src/main/java/org/c4marathon/assignment/service/MarathonService.java @@ -31,8 +31,8 @@ public class MarathonService { private final TransactionRepository transactionRepository; private final C4ThreadPoolExecutor threadPoolExecutor = new C4ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE); - public FinancialInfoRes getAllInfoWithLimit(String email) { - User user = userRepository.findUserByEmail(email) + public FinancialInfoRes getAllInfoWithLimit(Integer userId) { + User user = userRepository.findUserById(userId) .orElseThrow(() -> new BadRequestException("존재하지 않는 회원입니다.")); List accountResList = accountRepository.findAllAccountByUserId(user.getId()) @@ -57,8 +57,8 @@ public FinancialInfoRes getAllInfoWithLimit(String email) { return new FinancialInfoRes(accountResList, transactionResList); } - public FinancialInfoRes getAllInfoNotParallel(String email) { - User user = userRepository.findUserByEmail(email) + public FinancialInfoRes getAllInfoNotParallel(Integer userId) { + User user = userRepository.findUserById(userId) .orElseThrow(() -> new BadRequestException("존재하지 않는 회원입니다.")); List accountResList = accountRepository.findAllAccountByUserId(user.getId()) From 130e434734dbb6c980a0be76696b509b75ec3562 Mon Sep 17 00:00:00 2001 From: nyh365 <12nyk34@naver.com> Date: Fri, 15 Nov 2024 23:16:21 +0900 Subject: [PATCH 19/19] =?UTF-8?q?refactor:=20=EB=AF=B8=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/c4marathon/assignment/service/MarathonService.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/c4marathon/assignment/service/MarathonService.java b/src/main/java/org/c4marathon/assignment/service/MarathonService.java index 0134360..0ad7dd6 100644 --- a/src/main/java/org/c4marathon/assignment/service/MarathonService.java +++ b/src/main/java/org/c4marathon/assignment/service/MarathonService.java @@ -2,8 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; -import java.util.concurrent.Executor; import org.c4marathon.assignment.core.C4ThreadPoolExecutor; import org.c4marathon.assignment.dto.response.AccountRes;