From 6116f69b29fdad02c0856d2162afb37f188f8e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Fri, 31 May 2024 22:10:04 +0900 Subject: [PATCH 01/11] =?UTF-8?q?feat=20:=20=EA=B2=8C=EC=8B=9C=EB=AC=BC,?= =?UTF-8?q?=20=EB=A9=A4=EB=B2=84,=20=EA=B2=8C=EC=8B=9C=ED=8C=90=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=98=88=EC=99=B8=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 6 ++- .../demo/controller/ArticleController.java | 1 + .../dto/request/ArticleCreateRequest.java | 10 +++-- .../java/com/example/demo/domain/Article.java | 4 +- .../java/com/example/demo/domain/Member.java | 2 +- .../exception/errorcode/CommonErrorCode.java | 21 ++++++++++ .../demo/exception/errorcode/ErrorCode.java | 9 ++++ .../exception/exception/RestApiException.java | 11 +++++ .../handler/GlobalExceptionHandler.java | 41 +++++++++++++++++++ .../exception/response/ErrorResponse.java | 35 ++++++++++++++++ .../demo/repository/MemberRepositoryJdbc.java | 37 ++++++++++++----- .../example/demo/service/ArticleService.java | 14 +++++-- .../example/demo/service/BoardService.java | 10 ++++- .../example/demo/service/MemberService.java | 10 ++++- src/main/resources/application.yml | 2 +- 15 files changed, 186 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java create mode 100644 src/main/java/com/example/demo/exception/errorcode/ErrorCode.java create mode 100644 src/main/java/com/example/demo/exception/exception/RestApiException.java create mode 100644 src/main/java/com/example/demo/exception/handler/GlobalExceptionHandler.java create mode 100644 src/main/java/com/example/demo/exception/response/ErrorResponse.java diff --git a/build.gradle b/build.gradle index 728ec9c..41faa16 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,11 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-jdbc' - runtimeOnly 'com.mysql:mysql-connector-j' + implementation 'org.projectlombok:lombok:1.18.30' + implementation 'org.hibernate.validator:hibernate-validator' + runtimeOnly 'com.mysql:mysql-connector-j' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/com/example/demo/controller/ArticleController.java b/src/main/java/com/example/demo/controller/ArticleController.java index b28e4dd..8d775c4 100644 --- a/src/main/java/com/example/demo/controller/ArticleController.java +++ b/src/main/java/com/example/demo/controller/ArticleController.java @@ -3,6 +3,7 @@ import java.net.URI; import java.util.List; +import jakarta.validation.Valid; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; diff --git a/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java b/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java index d1f82a5..9165c36 100644 --- a/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java +++ b/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java @@ -1,10 +1,12 @@ package com.example.demo.controller.dto.request; +import jakarta.annotation.Nonnull; + public record ArticleCreateRequest( - Long authorId, - Long boardId, - String title, - String description + @Nonnull Long authorId, + @Nonnull Long boardId, + String title, + String description ) { } diff --git a/src/main/java/com/example/demo/domain/Article.java b/src/main/java/com/example/demo/domain/Article.java index e0183db..81a0cdd 100644 --- a/src/main/java/com/example/demo/domain/Article.java +++ b/src/main/java/com/example/demo/domain/Article.java @@ -5,11 +5,11 @@ public class Article { private Long id; - private Long authorId; + private final Long authorId; private Long boardId; private String title; private String content; - private LocalDateTime createdAt; + private final LocalDateTime createdAt; private LocalDateTime modifiedAt; public Article( diff --git a/src/main/java/com/example/demo/domain/Member.java b/src/main/java/com/example/demo/domain/Member.java index fe80d6b..5b7a4f4 100644 --- a/src/main/java/com/example/demo/domain/Member.java +++ b/src/main/java/com/example/demo/domain/Member.java @@ -5,7 +5,7 @@ public class Member { private Long id; private String name; private String email; - private String password; + private final String password; public Member(Long id, String name, String email, String password) { this.id = id; diff --git a/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java b/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java new file mode 100644 index 0000000..f309e61 --- /dev/null +++ b/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java @@ -0,0 +1,21 @@ +package com.example.demo.exception.errorcode; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +@Getter +@RequiredArgsConstructor +public enum CommonErrorCode implements ErrorCode { + EMAIL_ALREADY_EXIST(HttpStatus.CONFLICT, "이미 존재하는 이메일입니다."), + ARTICLE_NOT_EXIST(HttpStatus.NOT_FOUND, "입력한 ID에 해당하는 게시물이 존재하지 않습니다."), + MEMBER_NOT_EXIST(HttpStatus.NOT_FOUND, "입력한 ID에 해당하는 멤버가 존재하지 않습니다."), + BOARD_NOT_EXIST(HttpStatus.NOT_FOUND, "입력한 ID에 해당하는 게시판이 존재하지 않습니다."), + RESOURCE_NOT_FOUND(HttpStatus.NOT_FOUND, "Resource not exists"), + INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "Internal server error"), + ; + + private final HttpStatus httpStatus; + private final String message; + +} diff --git a/src/main/java/com/example/demo/exception/errorcode/ErrorCode.java b/src/main/java/com/example/demo/exception/errorcode/ErrorCode.java new file mode 100644 index 0000000..498d758 --- /dev/null +++ b/src/main/java/com/example/demo/exception/errorcode/ErrorCode.java @@ -0,0 +1,9 @@ +package com.example.demo.exception.errorcode; + +import org.springframework.http.HttpStatus; + +public interface ErrorCode { + String name(); + HttpStatus getHttpStatus(); + String getMessage(); +} diff --git a/src/main/java/com/example/demo/exception/exception/RestApiException.java b/src/main/java/com/example/demo/exception/exception/RestApiException.java new file mode 100644 index 0000000..b95bcb8 --- /dev/null +++ b/src/main/java/com/example/demo/exception/exception/RestApiException.java @@ -0,0 +1,11 @@ +package com.example.demo.exception.exception; + +import com.example.demo.exception.errorcode.ErrorCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class RestApiException extends RuntimeException{ + private final ErrorCode errorCode; +} diff --git a/src/main/java/com/example/demo/exception/handler/GlobalExceptionHandler.java b/src/main/java/com/example/demo/exception/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..e06f925 --- /dev/null +++ b/src/main/java/com/example/demo/exception/handler/GlobalExceptionHandler.java @@ -0,0 +1,41 @@ +package com.example.demo.exception.handler; + +import com.example.demo.exception.errorcode.CommonErrorCode; +import com.example.demo.exception.errorcode.ErrorCode; +import com.example.demo.exception.exception.RestApiException; +import com.example.demo.exception.response.ErrorResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +import java.util.List; +import java.util.stream.Collectors; + +@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { + + @ExceptionHandler(RestApiException.class) + public ResponseEntity handleCustonException(RestApiException e) { + return handleExceptionInternal(e.getErrorCode()); + } + private ResponseEntity handleExceptionInternal(ErrorCode errorCode) { + return ResponseEntity.status(errorCode.getHttpStatus()) + .body(makeErrorResponse(errorCode)); + } + + private ErrorResponse makeErrorResponse(ErrorCode errorCode) { + return ErrorResponse.builder() + .code(errorCode.name()) + .message(errorCode.getMessage()) + .build(); + } + +} diff --git a/src/main/java/com/example/demo/exception/response/ErrorResponse.java b/src/main/java/com/example/demo/exception/response/ErrorResponse.java new file mode 100644 index 0000000..c86dc4a --- /dev/null +++ b/src/main/java/com/example/demo/exception/response/ErrorResponse.java @@ -0,0 +1,35 @@ +package com.example.demo.exception.response; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.FieldError; + +import java.util.List; + +@Getter +@Builder +@RequiredArgsConstructor +public class ErrorResponse { + private final String code; + private final String message; + +/* @JsonInclude(JsonInclude.Include.NON_EMPTY) + private final List errors; + + @Getter + @Builder + @RequiredArgsConstructor + public static class ValidationError { + private final String field; + private final String message; + + public static ValidationError of(final FieldError fieldError) { + return ValidationError.builder() + .field(fieldError.getField()) + .message(fieldError.getDefaultMessage()) + .build(); + } + }*/ +} diff --git a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java index 30d2262..a1f3313 100644 --- a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java @@ -3,6 +3,9 @@ import java.sql.PreparedStatement; import java.util.List; +import com.example.demo.exception.errorcode.CommonErrorCode; +import com.example.demo.exception.exception.RestApiException; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.support.GeneratedKeyHolder; @@ -46,27 +49,41 @@ public Member findById(Long id) { @Override public Member insert(Member member) { - KeyHolder keyHolder = new GeneratedKeyHolder(); - jdbcTemplate.update(con -> { - PreparedStatement ps = con.prepareStatement(""" - INSERT INTO member (name, email, password) VALUES (?, ?, ?) - """, new String[]{"id"}); - ps.setString(1, member.getName()); - ps.setString(2, member.getEmail()); + try { + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(con -> { + PreparedStatement ps = con.prepareStatement(""" + + INSERT INTO member (name, email, password) VALUES (?, ?, ?) + """, new String[]{ + "id"}); + ps.setString(1, + member.getName()); + ps. + setString(2, member.getEmail()); ps.setString(3, member.getPassword()); return ps; }, keyHolder); return findById(keyHolder.getKey().longValue()); + } catch(RuntimeException e) { // 데이터 무결성 조건 위배 + throw new RestApiException(CommonErrorCode.EMAIL_ALREADY_EXIST); + } } @Override public Member update(Member member) { - jdbcTemplate.update(""" - UPDATE member + try { + jdbcTemplate.update(""" + + UPDATE member SET name = ?, email = ? WHERE id = ? - """, member.getName(), member.getEmail(), member.getId()); + """, member.getName(), member.getEmail(), member.getId + ()); return findById(member.getId()); + } catch (RuntimeException e) { // 데이터 무결성 조건 위배 + throw new RestApiException(CommonErrorCode.EMAIL_ALREADY_EXIST); + } } @Override diff --git a/src/main/java/com/example/demo/service/ArticleService.java b/src/main/java/com/example/demo/service/ArticleService.java index 7f8610b..7c786b3 100644 --- a/src/main/java/com/example/demo/service/ArticleService.java +++ b/src/main/java/com/example/demo/service/ArticleService.java @@ -2,6 +2,8 @@ import java.util.List; +import com.example.demo.exception.errorcode.CommonErrorCode; +import com.example.demo.exception.exception.RestApiException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,10 +36,14 @@ public ArticleService( } public ArticleResponse getById(Long id) { - Article article = articleRepository.findById(id); - Member member = memberRepository.findById(article.getAuthorId()); - Board board = boardRepository.findById(article.getBoardId()); - return ArticleResponse.of(article, member, board); + try { + Article article = articleRepository.findById(id); + Member member = memberRepository.findById(article.getAuthorId()); + Board board = boardRepository.findById(article.getBoardId()); + return ArticleResponse.of(article, member, board); + } catch (RuntimeException e) { + throw new RestApiException(CommonErrorCode.ARTICLE_NOT_EXIST); + } } public List getByBoardId(Long boardId) { diff --git a/src/main/java/com/example/demo/service/BoardService.java b/src/main/java/com/example/demo/service/BoardService.java index ffff891..b3d2ebd 100644 --- a/src/main/java/com/example/demo/service/BoardService.java +++ b/src/main/java/com/example/demo/service/BoardService.java @@ -2,6 +2,8 @@ import java.util.List; +import com.example.demo.exception.errorcode.CommonErrorCode; +import com.example.demo.exception.exception.RestApiException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -28,8 +30,12 @@ public List getBoards() { } public BoardResponse getBoardById(Long id) { - Board board = boardRepository.findById(id); - return BoardResponse.from(board); + try { + Board board = boardRepository.findById(id); + return BoardResponse.from(board); + } catch (RuntimeException e) { + throw new RestApiException(CommonErrorCode.BOARD_NOT_EXIST); + } } @Transactional diff --git a/src/main/java/com/example/demo/service/MemberService.java b/src/main/java/com/example/demo/service/MemberService.java index 04c1bc8..0cc7230 100644 --- a/src/main/java/com/example/demo/service/MemberService.java +++ b/src/main/java/com/example/demo/service/MemberService.java @@ -2,6 +2,8 @@ import java.util.List; +import com.example.demo.exception.errorcode.CommonErrorCode; +import com.example.demo.exception.exception.RestApiException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -22,8 +24,12 @@ public MemberService(MemberRepository memberRepository) { } public MemberResponse getById(Long id) { - Member member = memberRepository.findById(id); - return MemberResponse.from(member); + try { + Member member = memberRepository.findById(id); + return MemberResponse.from(member); + } catch(RuntimeException e) { + throw new RestApiException(CommonErrorCode.MEMBER_NOT_EXIST); + } } public List getAll() { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ff69a9e..2142af7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,5 +2,5 @@ spring: datasource: url: jdbc:mysql://localhost:3306/bcsd # 본인의 환경에 맞게 수정한다. username: root # 본인의 환경에 맞게 수정한다. - password: qwer1234 # 본인의 환경에 맞게 수정한다. + password: "6235" # 본인의 환경에 맞게 수정한다. driver-class-name: com.mysql.cj.jdbc.Driver From 41b6bbcb021b96b51a7087200c839be6c5bf7407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Sun, 2 Jun 2024 11:06:58 +0900 Subject: [PATCH 02/11] =?UTF-8?q?feat=20:=20=EC=83=9D=EC=84=B1=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../demo/controller/ArticleController.java | 2 +- .../demo/controller/BoardController.java | 3 +- .../demo/controller/MemberController.java | 3 +- .../dto/request/ArticleCreateRequest.java | 9 +-- .../dto/request/BoardCreateRequest.java | 4 +- .../dto/request/MemberCreateRequest.java | 8 ++- .../dto/request/MemberUpdateRequest.java | 6 +- .../exception/errorcode/CommonErrorCode.java | 16 +++-- .../handler/GlobalExceptionHandler.java | 24 +++++++ .../exception/response/ErrorResponse.java | 4 +- .../demo/repository/MemberRepositoryJdbc.java | 69 ++++++++----------- .../example/demo/service/ArticleService.java | 38 +++++++--- .../example/demo/service/BoardService.java | 8 ++- .../example/demo/service/MemberService.java | 18 +++-- 14 files changed, 135 insertions(+), 77 deletions(-) diff --git a/src/main/java/com/example/demo/controller/ArticleController.java b/src/main/java/com/example/demo/controller/ArticleController.java index 8d775c4..f74f3f2 100644 --- a/src/main/java/com/example/demo/controller/ArticleController.java +++ b/src/main/java/com/example/demo/controller/ArticleController.java @@ -46,7 +46,7 @@ public ResponseEntity getArticle( @PostMapping("/articles") public ResponseEntity crateArticle( - @RequestBody ArticleCreateRequest request + @Valid @RequestBody ArticleCreateRequest request ) { ArticleResponse response = articleService.create(request); return ResponseEntity.created(URI.create("/articles/" + response.id())).body(response); diff --git a/src/main/java/com/example/demo/controller/BoardController.java b/src/main/java/com/example/demo/controller/BoardController.java index ada81dc..6194662 100644 --- a/src/main/java/com/example/demo/controller/BoardController.java +++ b/src/main/java/com/example/demo/controller/BoardController.java @@ -2,6 +2,7 @@ import java.util.List; +import jakarta.validation.Valid; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -39,7 +40,7 @@ public BoardResponse getBoard( @PostMapping("/boards") public BoardResponse createBoard( - @RequestBody BoardCreateRequest request + @Valid @RequestBody BoardCreateRequest request ) { return boardService.createBoard(request); } diff --git a/src/main/java/com/example/demo/controller/MemberController.java b/src/main/java/com/example/demo/controller/MemberController.java index ddb18ec..c1fae43 100644 --- a/src/main/java/com/example/demo/controller/MemberController.java +++ b/src/main/java/com/example/demo/controller/MemberController.java @@ -2,6 +2,7 @@ import java.util.List; +import jakarta.validation.Valid; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -41,7 +42,7 @@ public ResponseEntity getMember( @PostMapping("/members") public ResponseEntity create( - @RequestBody MemberCreateRequest request + @Valid @RequestBody MemberCreateRequest request ) { MemberResponse response = memberService.create(request); return ResponseEntity.ok(response); diff --git a/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java b/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java index 9165c36..01439b4 100644 --- a/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java +++ b/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java @@ -1,12 +1,13 @@ package com.example.demo.controller.dto.request; import jakarta.annotation.Nonnull; +import jakarta.validation.constraints.NotNull; public record ArticleCreateRequest( - @Nonnull Long authorId, - @Nonnull Long boardId, - String title, - String description + @NotNull(message = "멤버ID를 입력해주세요.") Long authorId, + @NotNull(message = "게시판ID를 입력해주세요.") Long boardId, + @NotNull(message = "제목을 입력해주세요.") String title, + @NotNull(message = "내용을 입력해주세요.") String description ) { } diff --git a/src/main/java/com/example/demo/controller/dto/request/BoardCreateRequest.java b/src/main/java/com/example/demo/controller/dto/request/BoardCreateRequest.java index d1db14b..9347100 100644 --- a/src/main/java/com/example/demo/controller/dto/request/BoardCreateRequest.java +++ b/src/main/java/com/example/demo/controller/dto/request/BoardCreateRequest.java @@ -1,7 +1,9 @@ package com.example.demo.controller.dto.request; +import jakarta.validation.constraints.NotNull; + public record BoardCreateRequest( - String name + @NotNull(message = "이름을 입력해주세요.") String name ) { } diff --git a/src/main/java/com/example/demo/controller/dto/request/MemberCreateRequest.java b/src/main/java/com/example/demo/controller/dto/request/MemberCreateRequest.java index 44f74a5..bb58739 100644 --- a/src/main/java/com/example/demo/controller/dto/request/MemberCreateRequest.java +++ b/src/main/java/com/example/demo/controller/dto/request/MemberCreateRequest.java @@ -1,9 +1,11 @@ package com.example.demo.controller.dto.request; +import jakarta.validation.constraints.NotNull; + public record MemberCreateRequest( - String name, - String email, - String password + @NotNull(message = "이름을 입력해주세요.") String name, + @NotNull(message = "이메일을 입력해주세요.") String email, + @NotNull(message = "비밀번호를 입력해주세요") String password ) { } diff --git a/src/main/java/com/example/demo/controller/dto/request/MemberUpdateRequest.java b/src/main/java/com/example/demo/controller/dto/request/MemberUpdateRequest.java index 15f4345..79f701d 100644 --- a/src/main/java/com/example/demo/controller/dto/request/MemberUpdateRequest.java +++ b/src/main/java/com/example/demo/controller/dto/request/MemberUpdateRequest.java @@ -1,8 +1,10 @@ package com.example.demo.controller.dto.request; +import jakarta.validation.constraints.NotNull; + public record MemberUpdateRequest( - String name, - String email + @NotNull(message = "멤버의 이름을 적어주세요.") String name, + @NotNull(message = "멤버의 이메일을 적어주세요") String email ) { } diff --git a/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java b/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java index f309e61..68da632 100644 --- a/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java +++ b/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java @@ -8,14 +8,16 @@ @RequiredArgsConstructor public enum CommonErrorCode implements ErrorCode { EMAIL_ALREADY_EXIST(HttpStatus.CONFLICT, "이미 존재하는 이메일입니다."), - ARTICLE_NOT_EXIST(HttpStatus.NOT_FOUND, "입력한 ID에 해당하는 게시물이 존재하지 않습니다."), - MEMBER_NOT_EXIST(HttpStatus.NOT_FOUND, "입력한 ID에 해당하는 멤버가 존재하지 않습니다."), - BOARD_NOT_EXIST(HttpStatus.NOT_FOUND, "입력한 ID에 해당하는 게시판이 존재하지 않습니다."), - RESOURCE_NOT_FOUND(HttpStatus.NOT_FOUND, "Resource not exists"), - INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "Internal server error"), - ; + GET_ARTICLE_NOT_EXIST(HttpStatus.NOT_FOUND, "입력한 ID에 해당하는 게시물이 존재하지 않습니다."), + GET_MEMBER_NOT_EXIST(HttpStatus.NOT_FOUND, "입력한 ID에 해당하는 멤버가 존재하지 않습니다."), + GET_BOARD_NOT_EXIST(HttpStatus.NOT_FOUND, "입력한 ID에 해당하는 게시판이 존재하지 않습니다."), + POST_ARTICLE_NOT_EXIST(HttpStatus.BAD_REQUEST, "입력한 ID에 해당하는 게시물이 존재하지 않습니다."), + POST_MEMBER_NOT_EXIST(HttpStatus.BAD_REQUEST, "입력한 ID에 해당하는 멤버가 존재하지 않습니다."), + POST_BOARD_NOT_EXIST(HttpStatus.BAD_REQUEST, "입력한 ID에 해당하는 게시판이 존재하지 않습니다."), + UPDATE_BOARD_NOT_EXIST(HttpStatus.BAD_REQUEST,"입력한 ID에 해당하는 게시판이 존재하지 않습니다." ), + UPDATE_NAME_NULL(HttpStatus.BAD_REQUEST, "변경할 이름을 입력해주세요"), + UPDATE_EMAIL_NULL(HttpStatus.BAD_REQUEST, "변경할 이메일을 입력해주세요"); private final HttpStatus httpStatus; private final String message; - } diff --git a/src/main/java/com/example/demo/exception/handler/GlobalExceptionHandler.java b/src/main/java/com/example/demo/exception/handler/GlobalExceptionHandler.java index e06f925..fec8fe5 100644 --- a/src/main/java/com/example/demo/exception/handler/GlobalExceptionHandler.java +++ b/src/main/java/com/example/demo/exception/handler/GlobalExceptionHandler.java @@ -4,8 +4,10 @@ import com.example.demo.exception.errorcode.ErrorCode; import com.example.demo.exception.exception.RestApiException; import com.example.demo.exception.response.ErrorResponse; +import com.example.demo.exception.response.ErrorResponse.ValidationError; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; @@ -16,6 +18,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @RestControllerAdvice @@ -26,6 +29,7 @@ public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { public ResponseEntity handleCustonException(RestApiException e) { return handleExceptionInternal(e.getErrorCode()); } + private ResponseEntity handleExceptionInternal(ErrorCode errorCode) { return ResponseEntity.status(errorCode.getHttpStatus()) .body(makeErrorResponse(errorCode)); @@ -38,4 +42,24 @@ private ErrorResponse makeErrorResponse(ErrorCode errorCode) { .build(); } + @Override + protected ResponseEntity handleMethodArgumentNotValid( + MethodArgumentNotValidException ex, + HttpHeaders headers, + HttpStatusCode status, + WebRequest request) { + List validationErrors = ex.getBindingResult() + .getFieldErrors() + .stream() + .map(ValidationError::of) + .collect(Collectors.toList()); + + ErrorResponse errorResponse = ErrorResponse.builder() + .code("VALIDATION_ERROR") + .message("Validation failed for the request") + .errors(validationErrors) + .build(); + + return ResponseEntity.badRequest().body(errorResponse); + } } diff --git a/src/main/java/com/example/demo/exception/response/ErrorResponse.java b/src/main/java/com/example/demo/exception/response/ErrorResponse.java index c86dc4a..25861d4 100644 --- a/src/main/java/com/example/demo/exception/response/ErrorResponse.java +++ b/src/main/java/com/example/demo/exception/response/ErrorResponse.java @@ -15,7 +15,7 @@ public class ErrorResponse { private final String code; private final String message; -/* @JsonInclude(JsonInclude.Include.NON_EMPTY) + @JsonInclude(JsonInclude.Include.NON_EMPTY) private final List errors; @Getter @@ -31,5 +31,5 @@ public static ValidationError of(final FieldError fieldError) { .message(fieldError.getDefaultMessage()) .build(); } - }*/ + } } diff --git a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java index a1f3313..a4918c3 100644 --- a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java @@ -24,73 +24,62 @@ public MemberRepositoryJdbc(JdbcTemplate jdbcTemplate) { } private static final RowMapper memberRowMapper = (rs, rowNum) -> new Member( - rs.getLong("id"), - rs.getString("name"), - rs.getString("email"), - rs.getString("password") + rs.getLong("id"), + rs.getString("name"), + rs.getString("email"), + rs.getString("password") ); @Override public List findAll() { return jdbcTemplate.query(""" - SELECT id, name, email, password - FROM member - """, memberRowMapper); + SELECT id, name, email, password + FROM member + """, memberRowMapper); } @Override public Member findById(Long id) { return jdbcTemplate.queryForObject(""" - SELECT id, name, email, password - FROM member - WHERE id = ? - """, memberRowMapper, id); + SELECT id, name, email, password + FROM member + WHERE id = ? + """, memberRowMapper, id); } @Override public Member insert(Member member) { - try { - KeyHolder keyHolder = new GeneratedKeyHolder(); - jdbcTemplate.update(con -> { - PreparedStatement ps = con.prepareStatement(""" - - INSERT INTO member (name, email, password) VALUES (?, ?, ?) - """, new String[]{ - "id"}); - ps.setString(1, - member.getName()); - ps. - setString(2, member.getEmail()); + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(con -> { + PreparedStatement ps = con.prepareStatement(""" + INSERT INTO member (name, email, password) + VALUES (?, ?, ?) + """, new String[]{ + "id"}); + ps.setString(1, member.getName()); + ps.setString(2, member.getEmail()); ps.setString(3, member.getPassword()); return ps; }, keyHolder); return findById(keyHolder.getKey().longValue()); - } catch(RuntimeException e) { // 데이터 무결성 조건 위배 - throw new RestApiException(CommonErrorCode.EMAIL_ALREADY_EXIST); - } } @Override public Member update(Member member) { - try { - jdbcTemplate.update(""" - - UPDATE member - SET name = ?, email = ? - WHERE id = ? - """, member.getName(), member.getEmail(), member.getId - ()); + jdbcTemplate.update(""" + UPDATE member + SET name = ?, email = ? + WHERE id = ? + """, member.getName(), member.getEmail(), member.getId + ()); return findById(member.getId()); - } catch (RuntimeException e) { // 데이터 무결성 조건 위배 - throw new RestApiException(CommonErrorCode.EMAIL_ALREADY_EXIST); - } } @Override public void deleteById(Long id) { jdbcTemplate.update(""" - DELETE FROM member - WHERE id = ? - """, id); + DELETE FROM member + WHERE id = ? + """, id); } } diff --git a/src/main/java/com/example/demo/service/ArticleService.java b/src/main/java/com/example/demo/service/ArticleService.java index 7c786b3..a0fa1a9 100644 --- a/src/main/java/com/example/demo/service/ArticleService.java +++ b/src/main/java/com/example/demo/service/ArticleService.java @@ -36,14 +36,16 @@ public ArticleService( } public ArticleResponse getById(Long id) { + Article article; try { - Article article = articleRepository.findById(id); - Member member = memberRepository.findById(article.getAuthorId()); - Board board = boardRepository.findById(article.getBoardId()); - return ArticleResponse.of(article, member, board); + article = articleRepository.findById(id); } catch (RuntimeException e) { - throw new RestApiException(CommonErrorCode.ARTICLE_NOT_EXIST); + throw new RestApiException(CommonErrorCode.GET_ARTICLE_NOT_EXIST); } + + Member member = memberRepository.findById(article.getAuthorId()); + Board board = boardRepository.findById(article.getBoardId()); + return ArticleResponse.of(article, member, board); } public List getByBoardId(Long boardId) { @@ -66,8 +68,20 @@ public ArticleResponse create(ArticleCreateRequest request) { request.description() ); Article saved = articleRepository.insert(article); - Member member = memberRepository.findById(saved.getAuthorId()); - Board board = boardRepository.findById(saved.getBoardId()); + + Member member; + Board board; + try { + member = memberRepository.findById(saved.getAuthorId()); + } catch(RuntimeException e) { + throw new RestApiException(CommonErrorCode.POST_MEMBER_NOT_EXIST); + } + try { + board = boardRepository.findById(saved.getBoardId()); + } catch(RuntimeException e) { + throw new RestApiException(CommonErrorCode.POST_BOARD_NOT_EXIST); + } + // try-catch 문을 따로 사용하여 어디서 에러가 났는지 구분 return ArticleResponse.of(saved, member, board); } @@ -76,8 +90,16 @@ public ArticleResponse update(Long id, ArticleUpdateRequest request) { Article article = articleRepository.findById(id); article.update(request.boardId(), request.title(), request.description()); Article updated = articleRepository.update(article); + Member member = memberRepository.findById(updated.getAuthorId()); - Board board = boardRepository.findById(article.getBoardId()); + + Board board; + try { + board = boardRepository.findById(article.getBoardId()); + } catch(RuntimeException e) { + throw new RestApiException(CommonErrorCode.UPDATE_BOARD_NOT_EXIST); + } + return ArticleResponse.of(article, member, board); } diff --git a/src/main/java/com/example/demo/service/BoardService.java b/src/main/java/com/example/demo/service/BoardService.java index b3d2ebd..c854c2c 100644 --- a/src/main/java/com/example/demo/service/BoardService.java +++ b/src/main/java/com/example/demo/service/BoardService.java @@ -30,12 +30,14 @@ public List getBoards() { } public BoardResponse getBoardById(Long id) { + Board board; + try { - Board board = boardRepository.findById(id); - return BoardResponse.from(board); + board = boardRepository.findById(id); } catch (RuntimeException e) { - throw new RestApiException(CommonErrorCode.BOARD_NOT_EXIST); + throw new RestApiException(CommonErrorCode.GET_BOARD_NOT_EXIST); } + return BoardResponse.from(board); } @Transactional diff --git a/src/main/java/com/example/demo/service/MemberService.java b/src/main/java/com/example/demo/service/MemberService.java index 0cc7230..feda9ec 100644 --- a/src/main/java/com/example/demo/service/MemberService.java +++ b/src/main/java/com/example/demo/service/MemberService.java @@ -4,6 +4,7 @@ import com.example.demo.exception.errorcode.CommonErrorCode; import com.example.demo.exception.exception.RestApiException; +import jakarta.validation.Valid; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,12 +25,14 @@ public MemberService(MemberRepository memberRepository) { } public MemberResponse getById(Long id) { + Member member; + try { - Member member = memberRepository.findById(id); - return MemberResponse.from(member); + member = memberRepository.findById(id); } catch(RuntimeException e) { - throw new RestApiException(CommonErrorCode.MEMBER_NOT_EXIST); + throw new RestApiException(CommonErrorCode.GET_MEMBER_NOT_EXIST); } + return MemberResponse.from(member); } public List getAll() { @@ -56,7 +59,14 @@ public void delete(Long id) { public MemberResponse update(Long id, MemberUpdateRequest request) { Member member = memberRepository.findById(id); member.update(request.name(), request.email()); - memberRepository.update(member); + try { + memberRepository.update(member); + } catch(RuntimeException e) { + String errorMessage = e.getMessage(); + if(errorMessage.contains("Duplicate entry")) { + throw new RestApiException(CommonErrorCode.EMAIL_ALREADY_EXIST); + } + } return MemberResponse.from(member); } } From 90dab413a3de4ad58d6841464fb70d67d6882c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Sun, 2 Jun 2024 11:48:23 +0900 Subject: [PATCH 03/11] =?UTF-8?q?feat=20:=20=EC=82=AD=EC=A0=9C=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/errorcode/CommonErrorCode.java | 4 +++- .../com/example/demo/service/BoardService.java | 14 +++++++++++++- .../com/example/demo/service/MemberService.java | 16 +++++++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java b/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java index 68da632..0d61442 100644 --- a/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java +++ b/src/main/java/com/example/demo/exception/errorcode/CommonErrorCode.java @@ -16,7 +16,9 @@ public enum CommonErrorCode implements ErrorCode { POST_BOARD_NOT_EXIST(HttpStatus.BAD_REQUEST, "입력한 ID에 해당하는 게시판이 존재하지 않습니다."), UPDATE_BOARD_NOT_EXIST(HttpStatus.BAD_REQUEST,"입력한 ID에 해당하는 게시판이 존재하지 않습니다." ), UPDATE_NAME_NULL(HttpStatus.BAD_REQUEST, "변경할 이름을 입력해주세요"), - UPDATE_EMAIL_NULL(HttpStatus.BAD_REQUEST, "변경할 이메일을 입력해주세요"); + UPDATE_EMAIL_NULL(HttpStatus.BAD_REQUEST, "변경할 이메일을 입력해주세요"), + DELETE_ARTICLE_EXIST_IN_MEMBER(HttpStatus.BAD_REQUEST, "해당 멤버가 작성한 게시물이 존재합니다."), + DELETE_ARTICLE_EXIST_IN_BOARD(HttpStatus.BAD_REQUEST, "해당 게시판에 게시물이 존재합니다."); private final HttpStatus httpStatus; private final String message; diff --git a/src/main/java/com/example/demo/service/BoardService.java b/src/main/java/com/example/demo/service/BoardService.java index c854c2c..d72a12b 100644 --- a/src/main/java/com/example/demo/service/BoardService.java +++ b/src/main/java/com/example/demo/service/BoardService.java @@ -2,8 +2,10 @@ import java.util.List; +import com.example.demo.domain.Article; import com.example.demo.exception.errorcode.CommonErrorCode; import com.example.demo.exception.exception.RestApiException; +import com.example.demo.repository.ArticleRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,9 +20,11 @@ public class BoardService { private final BoardRepository boardRepository; + private final ArticleRepository articleRepository; - public BoardService(BoardRepository boardRepository) { + public BoardService(BoardRepository boardRepository, ArticleRepository articleRepository) { this.boardRepository = boardRepository; + this.articleRepository = articleRepository; } public List getBoards() { @@ -49,6 +53,14 @@ public BoardResponse createBoard(BoardCreateRequest request) { @Transactional public void deleteBoard(Long id) { + Boolean isArticleExist = articleRepository + .findAllByBoardId(id) + .stream() + .findAny() + .isPresent(); + if(isArticleExist) { + throw new RestApiException(CommonErrorCode.DELETE_ARTICLE_EXIST_IN_BOARD); + } boardRepository.deleteById(id); } diff --git a/src/main/java/com/example/demo/service/MemberService.java b/src/main/java/com/example/demo/service/MemberService.java index feda9ec..ab49f32 100644 --- a/src/main/java/com/example/demo/service/MemberService.java +++ b/src/main/java/com/example/demo/service/MemberService.java @@ -1,9 +1,12 @@ package com.example.demo.service; import java.util.List; +import java.util.Optional; +import com.example.demo.domain.Article; import com.example.demo.exception.errorcode.CommonErrorCode; import com.example.demo.exception.exception.RestApiException; +import com.example.demo.repository.ArticleRepository; import jakarta.validation.Valid; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,9 +22,11 @@ public class MemberService { private final MemberRepository memberRepository; + private final ArticleRepository articleRepository; - public MemberService(MemberRepository memberRepository) { + public MemberService(MemberRepository memberRepository, ArticleRepository articleRepository) { this.memberRepository = memberRepository; + this.articleRepository = articleRepository; } public MemberResponse getById(Long id) { @@ -52,6 +57,15 @@ public MemberResponse create(MemberCreateRequest request) { @Transactional public void delete(Long id) { + // 삭제 시 article이 참조하고 있는 경우 삭제를 못하게 해야됨. + Boolean isArticleExist = articleRepository.findAllByMemberId(id).stream() + .findAny() + .isPresent(); + + if(isArticleExist) { + throw new RestApiException(CommonErrorCode.DELETE_ARTICLE_EXIST_IN_MEMBER); + } + memberRepository.deleteById(id); } From 9b5395a4d8c1a497c3ef07b881593a23e1ca4860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:17:25 +0900 Subject: [PATCH 04/11] =?UTF-8?q?feat=20:=20MemberRepositoryJpa=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MemberRepositoryJpa 추가, Member에 @Entity 어노테이션 추가 --- build.gradle | 3 +- .../java/com/example/demo/domain/Board.java | 9 ++++ .../java/com/example/demo/domain/Member.java | 15 +++++- .../demo/repository/BoardRepositoryJpa.java | 42 ++++++++++++++++ .../demo/repository/MemberRepositoryJpa.java | 48 +++++++++++++++++++ 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/example/demo/repository/BoardRepositoryJpa.java create mode 100644 src/main/java/com/example/demo/repository/MemberRepositoryJpa.java diff --git a/build.gradle b/build.gradle index 41faa16..f07f4ff 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'org.projectlombok:lombok:1.18.30' implementation 'org.hibernate.validator:hibernate-validator' - runtimeOnly 'com.mysql:mysql-connector-j' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + runtimeOnly 'com.mysql:mysql-connector-j' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' diff --git a/src/main/java/com/example/demo/domain/Board.java b/src/main/java/com/example/demo/domain/Board.java index 992e2c6..070102a 100644 --- a/src/main/java/com/example/demo/domain/Board.java +++ b/src/main/java/com/example/demo/domain/Board.java @@ -1,7 +1,12 @@ package com.example.demo.domain; +import jakarta.persistence.*; + +@Entity public class Board { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @@ -14,6 +19,10 @@ public Board(String name) { this.name = name; } + public Board() { + + } + public Long getId() { return id; } diff --git a/src/main/java/com/example/demo/domain/Member.java b/src/main/java/com/example/demo/domain/Member.java index 5b7a4f4..2f5855b 100644 --- a/src/main/java/com/example/demo/domain/Member.java +++ b/src/main/java/com/example/demo/domain/Member.java @@ -1,11 +1,19 @@ package com.example.demo.domain; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +@Entity public class Member { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; - private final String password; + private String password; public Member(Long id, String name, String email, String password) { this.id = id; @@ -20,6 +28,11 @@ public Member(String name, String email, String password) { this.password = password; } + public Member() { + + } + + public void update(String name, String email) { this.name = name; this.email = email; diff --git a/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java b/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java new file mode 100644 index 0000000..99fbbef --- /dev/null +++ b/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java @@ -0,0 +1,42 @@ +package com.example.demo.repository; + +import com.example.demo.domain.Board; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Primary +@Repository +public class BoardRepositoryJpa implements BoardRepository{ + @PersistenceContext + EntityManager em; + + @Override + public Board findById(Long id) { + Board board = em.find(Board.class, id); + return board; + } + + @Override + public List findAll() { + return null; + } + + @Override + public Board insert(Board board) { + return null; + } + + @Override + public void deleteById(Long id) { + + } + + @Override + public Board update(Board board) { + return null; + } +} diff --git a/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java b/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java new file mode 100644 index 0000000..cbbd3ec --- /dev/null +++ b/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java @@ -0,0 +1,48 @@ +package com.example.demo.repository; + +import com.example.demo.domain.Member; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Primary +@Repository +public class MemberRepositoryJpa implements MemberRepository{ + + @PersistenceContext + EntityManager em; + + @Override + public Member findById(Long id) { + Member member = em.find(Member.class, id); + return member; + } + + @Override + public List findAll() { + List members = em.createQuery("select m from Member m", Member.class).getResultList(); + return members; + } + + @Override + public Member insert(Member member) { + em.persist(member); + return member; + } + + @Override + public Member update(Member member) { + Member findMember = em.find(Member.class, member.getId()); + findMember.update(member.getName(), member.getEmail()); //Transactional의 변경감지 + return findMember; + } + + @Override + public void deleteById(Long id) { + Member findMember = em.find(Member.class, id); + em.remove(findMember); + } +} From a9a01488cd721d7d525a2c1d5302393ee5f30c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:56:23 +0900 Subject: [PATCH 05/11] =?UTF-8?q?feat=20:=20BoardRepositoryJpa=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BoardRepositoryJpa추가 + Board도메인에 @Entity 추가 --- .../java/com/example/demo/domain/Article.java | 16 ++++- .../demo/repository/ArticleRepositoryJpa.java | 58 +++++++++++++++++++ .../demo/repository/BoardRepositoryJpa.java | 17 ++++-- .../example/demo/service/BoardService.java | 3 +- .../example/demo/service/MemberService.java | 11 +--- 5 files changed, 85 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java diff --git a/src/main/java/com/example/demo/domain/Article.java b/src/main/java/com/example/demo/domain/Article.java index 81a0cdd..4bea23d 100644 --- a/src/main/java/com/example/demo/domain/Article.java +++ b/src/main/java/com/example/demo/domain/Article.java @@ -1,15 +1,23 @@ package com.example.demo.domain; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + import java.time.LocalDateTime; +@Entity public class Article { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private final Long authorId; + private Long authorId; private Long boardId; private String title; private String content; - private final LocalDateTime createdAt; + private LocalDateTime createdAt; private LocalDateTime modifiedAt; public Article( @@ -40,6 +48,10 @@ public Article(Long authorId, Long boardId, String title, String content) { this.modifiedAt = LocalDateTime.now(); } + public Article() { + + } + public void update(Long boardId, String title, String description) { this.boardId = boardId; this.title = title; diff --git a/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java b/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java new file mode 100644 index 0000000..dc6b774 --- /dev/null +++ b/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java @@ -0,0 +1,58 @@ +package com.example.demo.repository; + +import com.example.demo.domain.Article; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.TypedQuery; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Primary +@Repository +public class ArticleRepositoryJpa implements ArticleRepository { + + @PersistenceContext + EntityManager em; + @Override + public List
findAll() { + List
articles = em.createQuery("select a from Article a", Article.class).getResultList(); + return articles; + } + + @Override + public List
findAllByBoardId(Long boardId) { + TypedQuery
query = em.createQuery("select a from Article a where a.boardId = :boardId", Article.class); + query.setParameter("boardId", boardId); + return query.getResultList(); + + } + + @Override + public List
findAllByMemberId(Long memberId) { + TypedQuery
query = em.createQuery("select a from Article a where a.authorId = :authorId", Article.class); + query.setParameter("authorId", memberId); + return query.getResultList(); + } + + @Override + public Article findById(Long id) { + return null; + } + + @Override + public Article insert(Article article) { + return null; + } + + @Override + public Article update(Article article) { + return null; + } + + @Override + public void deleteById(Long id) { + + } +} diff --git a/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java b/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java index 99fbbef..2f24e14 100644 --- a/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java +++ b/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java @@ -22,21 +22,26 @@ public Board findById(Long id) { @Override public List findAll() { - return null; + List boards = em.createQuery("select b from Board b", Board.class).getResultList(); + return boards; } @Override public Board insert(Board board) { - return null; + em.persist(board); + return board; } @Override - public void deleteById(Long id) { - + public Board update(Board board) { + Board findBoard = em.find(Board.class, board.getId()); + findBoard.update(board.getName()); + return findBoard; } @Override - public Board update(Board board) { - return null; + public void deleteById(Long id) { + Board board = em.find(Board.class, id); + em.remove(board); } } diff --git a/src/main/java/com/example/demo/service/BoardService.java b/src/main/java/com/example/demo/service/BoardService.java index d72a12b..5cc543c 100644 --- a/src/main/java/com/example/demo/service/BoardService.java +++ b/src/main/java/com/example/demo/service/BoardService.java @@ -68,7 +68,6 @@ public void deleteBoard(Long id) { public BoardResponse update(Long id, BoardUpdateRequest request) { Board board = boardRepository.findById(id); board.update(request.name()); - Board updated = boardRepository.update(board); - return BoardResponse.from(updated); + return BoardResponse.from(board); } } diff --git a/src/main/java/com/example/demo/service/MemberService.java b/src/main/java/com/example/demo/service/MemberService.java index ab49f32..394c1d9 100644 --- a/src/main/java/com/example/demo/service/MemberService.java +++ b/src/main/java/com/example/demo/service/MemberService.java @@ -31,13 +31,12 @@ public MemberService(MemberRepository memberRepository, ArticleRepository articl public MemberResponse getById(Long id) { Member member; - try { member = memberRepository.findById(id); } catch(RuntimeException e) { throw new RestApiException(CommonErrorCode.GET_MEMBER_NOT_EXIST); } - return MemberResponse.from(member); + return MemberResponse.from(member); } public List getAll() { @@ -73,14 +72,6 @@ public void delete(Long id) { public MemberResponse update(Long id, MemberUpdateRequest request) { Member member = memberRepository.findById(id); member.update(request.name(), request.email()); - try { - memberRepository.update(member); - } catch(RuntimeException e) { - String errorMessage = e.getMessage(); - if(errorMessage.contains("Duplicate entry")) { - throw new RestApiException(CommonErrorCode.EMAIL_ALREADY_EXIST); - } - } return MemberResponse.from(member); } } From 2d2f9c6f4e4ecbdab487747bdfd0b53ef0bef36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:02:52 +0900 Subject: [PATCH 06/11] =?UTF-8?q?feat=20:=20ArticleRepositoryJpa=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ArticleRepositoryJpa 추가, Article도메인에 @Entity 추가 --- .../example/demo/repository/ArticleRepositoryJpa.java | 9 ++++++--- .../java/com/example/demo/service/ArticleService.java | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java b/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java index dc6b774..d1894aa 100644 --- a/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java +++ b/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java @@ -38,12 +38,14 @@ public List
findAllByMemberId(Long memberId) { @Override public Article findById(Long id) { - return null; + Article article = em.find(Article.class, id); + return article; } @Override public Article insert(Article article) { - return null; + em.persist(article); + return article; } @Override @@ -53,6 +55,7 @@ public Article update(Article article) { @Override public void deleteById(Long id) { - + Article article = em.find(Article.class, id); + em.remove(article); } } diff --git a/src/main/java/com/example/demo/service/ArticleService.java b/src/main/java/com/example/demo/service/ArticleService.java index a0fa1a9..38a159b 100644 --- a/src/main/java/com/example/demo/service/ArticleService.java +++ b/src/main/java/com/example/demo/service/ArticleService.java @@ -89,9 +89,9 @@ public ArticleResponse create(ArticleCreateRequest request) { public ArticleResponse update(Long id, ArticleUpdateRequest request) { Article article = articleRepository.findById(id); article.update(request.boardId(), request.title(), request.description()); - Article updated = articleRepository.update(article); +// Article updated = articleRepository.update(article); - Member member = memberRepository.findById(updated.getAuthorId()); + Member member = memberRepository.findById(article.getAuthorId()); Board board; try { From 6e2c68a1848ac908c866c052406a2f3cc3abfde2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:24:48 +0900 Subject: [PATCH 07/11] =?UTF-8?q?feat=20:=20EntityManager=EC=9D=84=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=9C=20JPA=EB=A1=9C=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/ArticleCreateRequest.java | 2 +- .../java/com/example/demo/domain/Article.java | 84 +++++++++++++++---- .../java/com/example/demo/domain/Board.java | 10 +++ .../java/com/example/demo/domain/Member.java | 14 +++- .../repository/ArticleRepositoryJdbc.java | 2 + .../demo/repository/ArticleRepositoryJpa.java | 4 +- .../repository/ArticleRepositoryMemory.java | 2 + .../demo/repository/BoardRepositoryJdbc.java | 2 + .../repository/BoardRepositoryMemory.java | 2 + .../demo/repository/MemberRepositoryJdbc.java | 2 + .../repository/MemberRepositoryMemory.java | 2 + .../example/demo/service/ArticleService.java | 37 +++----- 12 files changed, 114 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java b/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java index 01439b4..6cb74de 100644 --- a/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java +++ b/src/main/java/com/example/demo/controller/dto/request/ArticleCreateRequest.java @@ -7,7 +7,7 @@ public record ArticleCreateRequest( @NotNull(message = "멤버ID를 입력해주세요.") Long authorId, @NotNull(message = "게시판ID를 입력해주세요.") Long boardId, @NotNull(message = "제목을 입력해주세요.") String title, - @NotNull(message = "내용을 입력해주세요.") String description + @NotNull(message = "내용을 입력해주세요.") String content ) { } diff --git a/src/main/java/com/example/demo/domain/Article.java b/src/main/java/com/example/demo/domain/Article.java index 4bea23d..7aa98d8 100644 --- a/src/main/java/com/example/demo/domain/Article.java +++ b/src/main/java/com/example/demo/domain/Article.java @@ -1,9 +1,6 @@ package com.example.demo.domain; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import java.time.LocalDateTime; @@ -12,15 +9,27 @@ public class Article { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "article_id") private Long id; - private Long authorId; - private Long boardId; +// private Long authorId; +// private Long boardId; + + @ManyToOne + @JoinColumn(name = "author_id") + private Member member; + + @ManyToOne + @JoinColumn(name = "board_id") + private Board board; + private String title; private String content; + @Column(name = "created_date") private LocalDateTime createdAt; + @Column(name = "modified_date") private LocalDateTime modifiedAt; - public Article( +/* public Article( Long id, Long authorId, Long boardId, @@ -45,20 +54,33 @@ public Article(Long authorId, Long boardId, String title, String content) { this.title = title; this.content = content; this.createdAt = LocalDateTime.now(); - this.modifiedAt = LocalDateTime.now(); - } + }*/ public Article() { } - public void update(Long boardId, String title, String description) { - this.boardId = boardId; + public void update(Board board, String title, String description) { + this.board = board; this.title = title; this.content = description; this.modifiedAt = LocalDateTime.now(); } + public void setMember(Member member) { + this.member = member; + member.getArticles().add(this); + } + + public void setBoard(Board board) { + this.board = board; + board.getArticles().add(this); + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + public void setId(Long id) { this.id = id; } @@ -71,13 +93,13 @@ public Long getId() { return id; } - public Long getAuthorId() { - return authorId; - } - - public Long getBoardId() { - return boardId; - } +// public Long getAuthorId() { +// return authorId; +// } +// +// public Long getBoardId() { +// return boardId; +// } public String getTitle() { return title; @@ -94,4 +116,30 @@ public LocalDateTime getCreatedAt() { public LocalDateTime getModifiedAt() { return modifiedAt; } + + public Member getMember() { + return member; + } + + public Board getBoard() { + return board; + } + + private void setTitle(String title) { + this.title = title; + } + + private void setContent(String content) { + this.content = content; + } + + public static Article createArticle(String title, String content, Member member, Board board) { + Article article = new Article(); + article.setTitle(title); + article.setContent(content); + article.setMember(member); + article.setBoard(board); + article.setCreatedAt(LocalDateTime.now()); + return article; + } } diff --git a/src/main/java/com/example/demo/domain/Board.java b/src/main/java/com/example/demo/domain/Board.java index 070102a..3203507 100644 --- a/src/main/java/com/example/demo/domain/Board.java +++ b/src/main/java/com/example/demo/domain/Board.java @@ -2,14 +2,20 @@ import jakarta.persistence.*; +import java.util.List; + @Entity public class Board { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "board_id") private Long id; private String name; + @OneToMany(mappedBy = "board") + private List
articles; + public Board(Long id, String name) { this.id = id; this.name = name; @@ -38,4 +44,8 @@ public String getName() { public void update(String name) { this.name = name; } + + public List
getArticles() { + return articles; + } } diff --git a/src/main/java/com/example/demo/domain/Member.java b/src/main/java/com/example/demo/domain/Member.java index 2f5855b..39b30b2 100644 --- a/src/main/java/com/example/demo/domain/Member.java +++ b/src/main/java/com/example/demo/domain/Member.java @@ -1,19 +1,21 @@ package com.example.demo.domain; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; + +import java.util.List; @Entity public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "member_id") private Long id; private String name; private String email; private String password; + @OneToMany(mappedBy = "member") + private List
articles; public Member(Long id, String name, String email, String password) { this.id = id; @@ -57,4 +59,8 @@ public String getEmail() { public String getPassword() { return password; } + + public List
getArticles() { + return articles; + } } diff --git a/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java b/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java index c9a272e..0ca6acf 100644 --- a/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java @@ -1,3 +1,4 @@ +/* package com.example.demo.repository; import java.sql.PreparedStatement; @@ -106,3 +107,4 @@ public void deleteById(Long id) { """, id); } } +*/ diff --git a/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java b/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java index d1894aa..af27fee 100644 --- a/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java +++ b/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java @@ -23,7 +23,7 @@ public List
findAll() { @Override public List
findAllByBoardId(Long boardId) { - TypedQuery
query = em.createQuery("select a from Article a where a.boardId = :boardId", Article.class); + TypedQuery
query = em.createQuery("select a from Article a where a.board.id = :boardId", Article.class); query.setParameter("boardId", boardId); return query.getResultList(); @@ -31,7 +31,7 @@ public List
findAllByBoardId(Long boardId) { @Override public List
findAllByMemberId(Long memberId) { - TypedQuery
query = em.createQuery("select a from Article a where a.authorId = :authorId", Article.class); + TypedQuery
query = em.createQuery("select a from Article a where a.member.id = :authorId", Article.class); query.setParameter("authorId", memberId); return query.getResultList(); } diff --git a/src/main/java/com/example/demo/repository/ArticleRepositoryMemory.java b/src/main/java/com/example/demo/repository/ArticleRepositoryMemory.java index 13ba78b..61ebede 100644 --- a/src/main/java/com/example/demo/repository/ArticleRepositoryMemory.java +++ b/src/main/java/com/example/demo/repository/ArticleRepositoryMemory.java @@ -1,3 +1,4 @@ +/* package com.example.demo.repository; import java.util.HashMap; @@ -68,3 +69,4 @@ public void deleteById(Long id) { articles.remove(id); } } +*/ diff --git a/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java b/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java index c4fd6f6..fd2982b 100644 --- a/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java @@ -1,3 +1,4 @@ +/* package com.example.demo.repository; import java.sql.PreparedStatement; @@ -70,3 +71,4 @@ public Board update(Board board) { ); } } +*/ diff --git a/src/main/java/com/example/demo/repository/BoardRepositoryMemory.java b/src/main/java/com/example/demo/repository/BoardRepositoryMemory.java index 8cf5ecf..99bfe6a 100644 --- a/src/main/java/com/example/demo/repository/BoardRepositoryMemory.java +++ b/src/main/java/com/example/demo/repository/BoardRepositoryMemory.java @@ -1,3 +1,4 @@ +/* package com.example.demo.repository; import java.util.HashMap; @@ -48,3 +49,4 @@ public Board update(Board board) { return boards.put(board.getId(), board); } } +*/ diff --git a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java index a4918c3..efcc8cb 100644 --- a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java @@ -1,3 +1,4 @@ +/* package com.example.demo.repository; import java.sql.PreparedStatement; @@ -83,3 +84,4 @@ public void deleteById(Long id) { """, id); } } +*/ diff --git a/src/main/java/com/example/demo/repository/MemberRepositoryMemory.java b/src/main/java/com/example/demo/repository/MemberRepositoryMemory.java index b4cf722..383a713 100644 --- a/src/main/java/com/example/demo/repository/MemberRepositoryMemory.java +++ b/src/main/java/com/example/demo/repository/MemberRepositoryMemory.java @@ -1,3 +1,4 @@ +/* package com.example.demo.repository; import java.util.HashMap; @@ -50,3 +51,4 @@ public void deleteById(Long id) { members.remove(id); } } +*/ diff --git a/src/main/java/com/example/demo/service/ArticleService.java b/src/main/java/com/example/demo/service/ArticleService.java index 38a159b..814d02c 100644 --- a/src/main/java/com/example/demo/service/ArticleService.java +++ b/src/main/java/com/example/demo/service/ArticleService.java @@ -43,44 +43,36 @@ public ArticleResponse getById(Long id) { throw new RestApiException(CommonErrorCode.GET_ARTICLE_NOT_EXIST); } - Member member = memberRepository.findById(article.getAuthorId()); - Board board = boardRepository.findById(article.getBoardId()); - return ArticleResponse.of(article, member, board); + return ArticleResponse.of(article, article.getMember(), article.getBoard()); } public List getByBoardId(Long boardId) { List
articles = articleRepository.findAllByBoardId(boardId); return articles.stream() .map(article -> { - Member member = memberRepository.findById(article.getAuthorId()); - Board board = boardRepository.findById(article.getBoardId()); - return ArticleResponse.of(article, member, board); + return ArticleResponse.of(article, article.getMember(), article.getBoard()); }) .toList(); } @Transactional public ArticleResponse create(ArticleCreateRequest request) { - Article article = new Article( - request.authorId(), - request.boardId(), - request.title(), - request.description() - ); - Article saved = articleRepository.insert(article); - Member member; Board board; try { - member = memberRepository.findById(saved.getAuthorId()); + member = memberRepository.findById(request.authorId()); } catch(RuntimeException e) { throw new RestApiException(CommonErrorCode.POST_MEMBER_NOT_EXIST); } try { - board = boardRepository.findById(saved.getBoardId()); + board = boardRepository.findById(request.boardId()); } catch(RuntimeException e) { throw new RestApiException(CommonErrorCode.POST_BOARD_NOT_EXIST); } + + Article article = Article.createArticle(request.title(), request.content(), member, board); + Article saved = articleRepository.insert(article); + // try-catch 문을 따로 사용하여 어디서 에러가 났는지 구분 return ArticleResponse.of(saved, member, board); } @@ -88,19 +80,16 @@ public ArticleResponse create(ArticleCreateRequest request) { @Transactional public ArticleResponse update(Long id, ArticleUpdateRequest request) { Article article = articleRepository.findById(id); - article.update(request.boardId(), request.title(), request.description()); -// Article updated = articleRepository.update(article); - - Member member = memberRepository.findById(article.getAuthorId()); - Board board; try { - board = boardRepository.findById(article.getBoardId()); + board = boardRepository.findById(request.boardId()); } catch(RuntimeException e) { - throw new RestApiException(CommonErrorCode.UPDATE_BOARD_NOT_EXIST); + throw new RestApiException(CommonErrorCode.POST_BOARD_NOT_EXIST); } - return ArticleResponse.of(article, member, board); + article.update(board, request.title(), request.description()); +// Article updated = articleRepository.update(article); + return ArticleResponse.of(article, article.getMember(), board); } @Transactional From 0d243a7dcd3dd26d006a11f3a1a09421c9767769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:53:24 +0900 Subject: [PATCH 08/11] =?UTF-8?q?feat=20:=20BoardRepository=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SpringDataJpa형식으로 변경 (extends JpaRepository --- .../demo/repository/BoardRepository.java | 14 +-- .../demo/repository/BoardRepositoryJpa.java | 95 ++++++++++--------- .../example/demo/service/BoardService.java | 14 ++- 3 files changed, 57 insertions(+), 66 deletions(-) diff --git a/src/main/java/com/example/demo/repository/BoardRepository.java b/src/main/java/com/example/demo/repository/BoardRepository.java index cc2dfd0..439813f 100644 --- a/src/main/java/com/example/demo/repository/BoardRepository.java +++ b/src/main/java/com/example/demo/repository/BoardRepository.java @@ -1,18 +1,10 @@ package com.example.demo.repository; import java.util.List; +import java.util.Optional; import com.example.demo.domain.Board; +import org.springframework.data.jpa.repository.JpaRepository; -public interface BoardRepository { - - List findAll(); - - Board findById(Long id); - - Board insert(Board board); - - void deleteById(Long id); - - Board update(Board board); +public interface BoardRepository extends JpaRepository { } diff --git a/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java b/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java index 2f24e14..b0f7a0c 100644 --- a/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java +++ b/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java @@ -1,47 +1,48 @@ -package com.example.demo.repository; - -import com.example.demo.domain.Board; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Primary -@Repository -public class BoardRepositoryJpa implements BoardRepository{ - @PersistenceContext - EntityManager em; - - @Override - public Board findById(Long id) { - Board board = em.find(Board.class, id); - return board; - } - - @Override - public List findAll() { - List boards = em.createQuery("select b from Board b", Board.class).getResultList(); - return boards; - } - - @Override - public Board insert(Board board) { - em.persist(board); - return board; - } - - @Override - public Board update(Board board) { - Board findBoard = em.find(Board.class, board.getId()); - findBoard.update(board.getName()); - return findBoard; - } - - @Override - public void deleteById(Long id) { - Board board = em.find(Board.class, id); - em.remove(board); - } -} +//package com.example.demo.repository; +// +//import com.example.demo.domain.Board; +//import jakarta.persistence.EntityManager; +//import jakarta.persistence.PersistenceContext; +//import org.springframework.context.annotation.Primary; +//import org.springframework.stereotype.Repository; +// +//import java.util.List; +//import java.util.Optional; +// +//@Primary +//@Repository +//public class BoardRepositoryJpa implements BoardRepository{ +// @PersistenceContext +// EntityManager em; +// +// @Override +// public Optional findById(Long id) { +// Board board = em.find(Board.class, id); +// return board; +// } +// +// @Override +// public List findAll() { +// List boards = em.createQuery("select b from Board b", Board.class).getResultList(); +// return boards; +// } +// +// @Override +// public Board insert(Board board) { +// em.persist(board); +// return board; +// } +// +// @Override +// public Board update(Board board) { +// Board findBoard = em.find(Board.class, board.getId()); +// findBoard.update(board.getName()); +// return findBoard; +// } +// +// @Override +// public void deleteById(Long id) { +// Board board = em.find(Board.class, id); +// em.remove(board); +// } +//} diff --git a/src/main/java/com/example/demo/service/BoardService.java b/src/main/java/com/example/demo/service/BoardService.java index 5cc543c..81a5e08 100644 --- a/src/main/java/com/example/demo/service/BoardService.java +++ b/src/main/java/com/example/demo/service/BoardService.java @@ -1,6 +1,7 @@ package com.example.demo.service; import java.util.List; +import java.util.Optional; import com.example.demo.domain.Article; import com.example.demo.exception.errorcode.CommonErrorCode; @@ -34,20 +35,17 @@ public List getBoards() { } public BoardResponse getBoardById(Long id) { - Board board; + Optional board; - try { - board = boardRepository.findById(id); - } catch (RuntimeException e) { - throw new RestApiException(CommonErrorCode.GET_BOARD_NOT_EXIST); - } - return BoardResponse.from(board); + board = boardRepository.findById(id); + + return board.map(BoardResponse::from).orElseThrow(() -> new RestApiException(CommonErrorCode.GET_BOARD_NOT_EXIST)); } @Transactional public BoardResponse createBoard(BoardCreateRequest request) { Board board = new Board(request.name()); - Board saved = boardRepository.insert(board); + Board saved = boardRepository.save(board); return BoardResponse.from(saved); } From 0d6aabf594d333618b9bfbfb37f04f55efe5490a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:01:57 +0900 Subject: [PATCH 09/11] =?UTF-8?q?feat=20:=20MemberRepository=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SpringDataJpa형식으로 변경 (extends JpaRepository --- .../example/demo/repository/MemberRepository.java | 12 ++---------- .../demo/repository/MemberRepositoryJpa.java | 2 ++ .../com/example/demo/service/BoardService.java | 4 +--- .../com/example/demo/service/MemberService.java | 14 +++++--------- 4 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/example/demo/repository/MemberRepository.java b/src/main/java/com/example/demo/repository/MemberRepository.java index 8e2ad14..c399cb9 100644 --- a/src/main/java/com/example/demo/repository/MemberRepository.java +++ b/src/main/java/com/example/demo/repository/MemberRepository.java @@ -3,16 +3,8 @@ import java.util.List; import com.example.demo.domain.Member; +import org.springframework.data.jpa.repository.JpaRepository; -public interface MemberRepository { +public interface MemberRepository extends JpaRepository { - List findAll(); - - Member findById(Long id); - - Member insert(Member member); - - Member update(Member member); - - void deleteById(Long id); } diff --git a/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java b/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java index cbbd3ec..32f8b84 100644 --- a/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java +++ b/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java @@ -1,3 +1,4 @@ +/* package com.example.demo.repository; import com.example.demo.domain.Member; @@ -46,3 +47,4 @@ public void deleteById(Long id) { em.remove(findMember); } } +*/ diff --git a/src/main/java/com/example/demo/service/BoardService.java b/src/main/java/com/example/demo/service/BoardService.java index 81a5e08..7ecf522 100644 --- a/src/main/java/com/example/demo/service/BoardService.java +++ b/src/main/java/com/example/demo/service/BoardService.java @@ -36,9 +36,7 @@ public List getBoards() { public BoardResponse getBoardById(Long id) { Optional board; - board = boardRepository.findById(id); - return board.map(BoardResponse::from).orElseThrow(() -> new RestApiException(CommonErrorCode.GET_BOARD_NOT_EXIST)); } @@ -64,7 +62,7 @@ public void deleteBoard(Long id) { @Transactional public BoardResponse update(Long id, BoardUpdateRequest request) { - Board board = boardRepository.findById(id); + Board board = boardRepository.findById(id).orElseThrow(() -> new RestApiException(CommonErrorCode.GET_BOARD_NOT_EXIST)); board.update(request.name()); return BoardResponse.from(board); } diff --git a/src/main/java/com/example/demo/service/MemberService.java b/src/main/java/com/example/demo/service/MemberService.java index 394c1d9..e078f02 100644 --- a/src/main/java/com/example/demo/service/MemberService.java +++ b/src/main/java/com/example/demo/service/MemberService.java @@ -30,13 +30,9 @@ public MemberService(MemberRepository memberRepository, ArticleRepository articl } public MemberResponse getById(Long id) { - Member member; - try { - member = memberRepository.findById(id); - } catch(RuntimeException e) { - throw new RestApiException(CommonErrorCode.GET_MEMBER_NOT_EXIST); - } - return MemberResponse.from(member); + Optional member; + member = memberRepository.findById(id); + return member.map(MemberResponse::from).orElseThrow(() -> new RestApiException(CommonErrorCode.GET_MEMBER_NOT_EXIST)); } public List getAll() { @@ -48,7 +44,7 @@ public List getAll() { @Transactional public MemberResponse create(MemberCreateRequest request) { - Member member = memberRepository.insert( + Member member = memberRepository.save( new Member(request.name(), request.email(), request.password()) ); return MemberResponse.from(member); @@ -70,7 +66,7 @@ public void delete(Long id) { @Transactional public MemberResponse update(Long id, MemberUpdateRequest request) { - Member member = memberRepository.findById(id); + Member member = memberRepository.findById(id).orElseThrow(() -> new RestApiException(CommonErrorCode.GET_MEMBER_NOT_EXIST)); member.update(request.name(), request.email()); return MemberResponse.from(member); } From ee82afdc4c2bbcf97fbeb499492bfe8342f5e447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:29:54 +0900 Subject: [PATCH 10/11] =?UTF-8?q?feat=20:=20ArticleRepository=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SpringDataJpa형식으로 변경 (extends JpaRepository --- .../demo/repository/ArticleRepository.java | 19 ++-------- .../demo/repository/ArticleRepositoryJpa.java | 2 + .../example/demo/service/ArticleService.java | 37 +++++-------------- 3 files changed, 16 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/example/demo/repository/ArticleRepository.java b/src/main/java/com/example/demo/repository/ArticleRepository.java index be3ebd4..469549d 100644 --- a/src/main/java/com/example/demo/repository/ArticleRepository.java +++ b/src/main/java/com/example/demo/repository/ArticleRepository.java @@ -3,20 +3,9 @@ import java.util.List; import com.example.demo.domain.Article; +import org.springframework.data.jpa.repository.JpaRepository; -public interface ArticleRepository { - - List
findAll(); - - List
findAllByBoardId(Long boardId); - - List
findAllByMemberId(Long memberId); - - Article findById(Long id); - - Article insert(Article article); - - Article update(Article article); - - void deleteById(Long id); +public interface ArticleRepository extends JpaRepository { + List
findAllByBoardId(Long id); + List
findAllByMemberId(Long id); } diff --git a/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java b/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java index af27fee..0a17ad7 100644 --- a/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java +++ b/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java @@ -1,3 +1,4 @@ +/* package com.example.demo.repository; import com.example.demo.domain.Article; @@ -59,3 +60,4 @@ public void deleteById(Long id) { em.remove(article); } } +*/ diff --git a/src/main/java/com/example/demo/service/ArticleService.java b/src/main/java/com/example/demo/service/ArticleService.java index 814d02c..4ed470c 100644 --- a/src/main/java/com/example/demo/service/ArticleService.java +++ b/src/main/java/com/example/demo/service/ArticleService.java @@ -1,6 +1,7 @@ package com.example.demo.service; import java.util.List; +import java.util.Optional; import com.example.demo.exception.errorcode.CommonErrorCode; import com.example.demo.exception.exception.RestApiException; @@ -36,14 +37,9 @@ public ArticleService( } public ArticleResponse getById(Long id) { - Article article; - try { - article = articleRepository.findById(id); - } catch (RuntimeException e) { - throw new RestApiException(CommonErrorCode.GET_ARTICLE_NOT_EXIST); - } - - return ArticleResponse.of(article, article.getMember(), article.getBoard()); + Optional
article; + article = articleRepository.findById(id); + return article.map(a -> ArticleResponse.of(a, a.getMember(), a.getBoard())).orElseThrow(() -> new RestApiException(CommonErrorCode.GET_ARTICLE_NOT_EXIST)); } public List getByBoardId(Long boardId) { @@ -59,36 +55,23 @@ public List getByBoardId(Long boardId) { public ArticleResponse create(ArticleCreateRequest request) { Member member; Board board; - try { - member = memberRepository.findById(request.authorId()); - } catch(RuntimeException e) { - throw new RestApiException(CommonErrorCode.POST_MEMBER_NOT_EXIST); - } - try { - board = boardRepository.findById(request.boardId()); - } catch(RuntimeException e) { - throw new RestApiException(CommonErrorCode.POST_BOARD_NOT_EXIST); - } + + member = memberRepository.findById(request.authorId()).orElseThrow(() -> new RestApiException(CommonErrorCode.GET_MEMBER_NOT_EXIST)); + board = boardRepository.findById(request.boardId()).orElseThrow(() -> new RestApiException(CommonErrorCode.GET_BOARD_NOT_EXIST)); Article article = Article.createArticle(request.title(), request.content(), member, board); - Article saved = articleRepository.insert(article); + Article saved = articleRepository.save(article); - // try-catch 문을 따로 사용하여 어디서 에러가 났는지 구분 return ArticleResponse.of(saved, member, board); } @Transactional public ArticleResponse update(Long id, ArticleUpdateRequest request) { - Article article = articleRepository.findById(id); + Article article = articleRepository.findById(id).orElseThrow(() -> new RestApiException(CommonErrorCode.GET_ARTICLE_NOT_EXIST)); Board board; - try { - board = boardRepository.findById(request.boardId()); - } catch(RuntimeException e) { - throw new RestApiException(CommonErrorCode.POST_BOARD_NOT_EXIST); - } + board = boardRepository.findById(request.boardId()).orElseThrow(() -> new RestApiException(CommonErrorCode.GET_BOARD_NOT_EXIST)); article.update(board, request.title(), request.description()); -// Article updated = articleRepository.update(article); return ArticleResponse.of(article, article.getMember(), board); } From 3d94143f204da94ae87d0edf9054bb11aa110bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=AC=EA=B2=BD=ED=98=84?= <121675605+yeokyunghyun@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:38:25 +0900 Subject: [PATCH 11/11] =?UTF-8?q?feat=20:=20=EC=98=81=EC=86=8D=EC=84=B1=20?= =?UTF-8?q?=EC=A0=84=EC=9D=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/demo/domain/Article.java | 2 +- src/main/java/com/example/demo/domain/Board.java | 4 +++- src/main/java/com/example/demo/domain/Member.java | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/example/demo/domain/Article.java b/src/main/java/com/example/demo/domain/Article.java index 7aa98d8..ea24ec6 100644 --- a/src/main/java/com/example/demo/domain/Article.java +++ b/src/main/java/com/example/demo/domain/Article.java @@ -14,7 +14,7 @@ public class Article { // private Long authorId; // private Long boardId; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "author_id") private Member member; diff --git a/src/main/java/com/example/demo/domain/Board.java b/src/main/java/com/example/demo/domain/Board.java index 3203507..2f5c366 100644 --- a/src/main/java/com/example/demo/domain/Board.java +++ b/src/main/java/com/example/demo/domain/Board.java @@ -4,6 +4,8 @@ import java.util.List; +import static jakarta.persistence.CascadeType.ALL; + @Entity public class Board { @@ -13,7 +15,7 @@ public class Board { private Long id; private String name; - @OneToMany(mappedBy = "board") + @OneToMany(mappedBy = "board", orphanRemoval = true, cascade = ALL) private List
articles; public Board(Long id, String name) { diff --git a/src/main/java/com/example/demo/domain/Member.java b/src/main/java/com/example/demo/domain/Member.java index 39b30b2..d2085c0 100644 --- a/src/main/java/com/example/demo/domain/Member.java +++ b/src/main/java/com/example/demo/domain/Member.java @@ -4,6 +4,8 @@ import java.util.List; +import static jakarta.persistence.CascadeType.ALL; + @Entity public class Member { @@ -14,7 +16,7 @@ public class Member { private String name; private String email; private String password; - @OneToMany(mappedBy = "member") + @OneToMany(mappedBy = "member", orphanRemoval = true, cascade = ALL) private List
articles; public Member(Long id, String name, String email, String password) {