From 75b1384868396e9c755b0687fb11f19aa454416a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8E=E1=85=AC=E1=84=8C=E1=85=AE=E1=86=AB=E1=84=92?= =?UTF-8?q?=E1=85=A9?= Date: Wed, 29 May 2024 00:37:31 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=EA=B3=BC=EC=A0=9C=20=EC=88=98?= =?UTF-8?q?=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/demo/controller/BoardController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/example/demo/controller/BoardController.java b/src/main/java/com/example/demo/controller/BoardController.java index ada81dc..baf6946 100644 --- a/src/main/java/com/example/demo/controller/BoardController.java +++ b/src/main/java/com/example/demo/controller/BoardController.java @@ -18,7 +18,7 @@ @RestController public class BoardController { - + // 과제 수행함 private final BoardService boardService; public BoardController(BoardService boardService) { From 8bf4897906c5f75bb2513e52472fcb18db0a5404 Mon Sep 17 00:00:00 2001 From: FrozenInclude Date: Tue, 4 Jun 2024 04:52:09 +0900 Subject: [PATCH 2/8] implements Exception Handling --- .../demo/AOPexception/ExceptHandler.java | 48 ++++++++++ .../Exception/DeleteExistedExcepton.java | 8 ++ .../Exception/GetNotFoundException.java | 8 ++ .../PostIllegalArgumemtException.java | 8 ++ .../Exception/PostNotFoundException.java | 8 ++ .../Exception/PutDuplicatedException.java | 8 ++ .../Exception/PutNotFoundException.java | 8 ++ .../demo/repository/ArticleRepository.java | 2 + .../repository/ArticleRepositoryJdbc.java | 91 ++++++++++++------- .../repository/ArticleRepositoryMemory.java | 59 ------------ .../demo/repository/BoardRepositoryJdbc.java | 9 +- .../repository/BoardRepositoryMemory.java | 50 ---------- .../demo/repository/MemberRepository.java | 2 + .../demo/repository/MemberRepositoryJdbc.java | 61 ++++++++----- .../repository/MemberRepositoryMemory.java | 52 ----------- .../example/demo/service/ArticleService.java | 80 ++++++++++------ .../example/demo/service/BoardService.java | 18 +++- .../example/demo/service/MemberService.java | 37 ++++++-- src/main/resources/application.yml | 2 +- 19 files changed, 298 insertions(+), 261 deletions(-) create mode 100644 src/main/java/com/example/demo/AOPexception/ExceptHandler.java create mode 100644 src/main/java/com/example/demo/AOPexception/Exception/DeleteExistedExcepton.java create mode 100644 src/main/java/com/example/demo/AOPexception/Exception/GetNotFoundException.java create mode 100644 src/main/java/com/example/demo/AOPexception/Exception/PostIllegalArgumemtException.java create mode 100644 src/main/java/com/example/demo/AOPexception/Exception/PostNotFoundException.java create mode 100644 src/main/java/com/example/demo/AOPexception/Exception/PutDuplicatedException.java create mode 100644 src/main/java/com/example/demo/AOPexception/Exception/PutNotFoundException.java delete mode 100644 src/main/java/com/example/demo/repository/ArticleRepositoryMemory.java delete mode 100644 src/main/java/com/example/demo/repository/BoardRepositoryMemory.java delete mode 100644 src/main/java/com/example/demo/repository/MemberRepositoryMemory.java diff --git a/src/main/java/com/example/demo/AOPexception/ExceptHandler.java b/src/main/java/com/example/demo/AOPexception/ExceptHandler.java new file mode 100644 index 0000000..fdd2750 --- /dev/null +++ b/src/main/java/com/example/demo/AOPexception/ExceptHandler.java @@ -0,0 +1,48 @@ +package com.example.demo.AOPexception; + +import com.example.demo.AOPexception.Exception.*; +import org.apache.coyote.BadRequestException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class ExceptHandler { + @ExceptionHandler + public ResponseEntity handleException(GetNotFoundException e) { + return new ResponseEntity<>(new ErrorResponse(e.getMessage()),HttpStatus.NOT_FOUND); + } + @ExceptionHandler + public ResponseEntity handleException(PutDuplicatedException e) { + return new ResponseEntity<>(new ErrorResponse(e.getMessage()),HttpStatus.CONFLICT); + } + @ExceptionHandler + public ResponseEntity handleException(PutNotFoundException e) { + return new ResponseEntity<>(new ErrorResponse(e.getMessage()),HttpStatus.BAD_REQUEST); + } + @ExceptionHandler + public ResponseEntity handleException(PostIllegalArgumemtException e) { + return new ResponseEntity<>(new ErrorResponse(e.getMessage()),HttpStatus.BAD_REQUEST); + } + @ExceptionHandler + public ResponseEntity handleException(PostNotFoundException e) { + return new ResponseEntity<>(new ErrorResponse(e.getMessage()),HttpStatus.BAD_REQUEST); + } + @ExceptionHandler + public ResponseEntity handleException(DeleteExistedExcepton e) { + return new ResponseEntity<>(new ErrorResponse(e.getMessage()),HttpStatus.BAD_REQUEST); + } + + static class ErrorResponse { + String message; + + ErrorResponse(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + } +} diff --git a/src/main/java/com/example/demo/AOPexception/Exception/DeleteExistedExcepton.java b/src/main/java/com/example/demo/AOPexception/Exception/DeleteExistedExcepton.java new file mode 100644 index 0000000..5061984 --- /dev/null +++ b/src/main/java/com/example/demo/AOPexception/Exception/DeleteExistedExcepton.java @@ -0,0 +1,8 @@ +package com.example.demo.AOPexception.Exception; + +public class DeleteExistedExcepton extends RuntimeException{ + public DeleteExistedExcepton(String msg) + { + super(msg); + } +} diff --git a/src/main/java/com/example/demo/AOPexception/Exception/GetNotFoundException.java b/src/main/java/com/example/demo/AOPexception/Exception/GetNotFoundException.java new file mode 100644 index 0000000..10c1e90 --- /dev/null +++ b/src/main/java/com/example/demo/AOPexception/Exception/GetNotFoundException.java @@ -0,0 +1,8 @@ +package com.example.demo.AOPexception.Exception; + +public class GetNotFoundException extends RuntimeException{ + public GetNotFoundException(String msg) + { + super(msg); + } +} diff --git a/src/main/java/com/example/demo/AOPexception/Exception/PostIllegalArgumemtException.java b/src/main/java/com/example/demo/AOPexception/Exception/PostIllegalArgumemtException.java new file mode 100644 index 0000000..a930bb0 --- /dev/null +++ b/src/main/java/com/example/demo/AOPexception/Exception/PostIllegalArgumemtException.java @@ -0,0 +1,8 @@ +package com.example.demo.AOPexception.Exception; + +public class PostIllegalArgumemtException extends RuntimeException{ + public PostIllegalArgumemtException(String msg) + { + super(msg); + } +} diff --git a/src/main/java/com/example/demo/AOPexception/Exception/PostNotFoundException.java b/src/main/java/com/example/demo/AOPexception/Exception/PostNotFoundException.java new file mode 100644 index 0000000..57f33bb --- /dev/null +++ b/src/main/java/com/example/demo/AOPexception/Exception/PostNotFoundException.java @@ -0,0 +1,8 @@ +package com.example.demo.AOPexception.Exception; + +public class PostNotFoundException extends RuntimeException{ + public PostNotFoundException(String msg) + { + super(msg); + } +} diff --git a/src/main/java/com/example/demo/AOPexception/Exception/PutDuplicatedException.java b/src/main/java/com/example/demo/AOPexception/Exception/PutDuplicatedException.java new file mode 100644 index 0000000..8844268 --- /dev/null +++ b/src/main/java/com/example/demo/AOPexception/Exception/PutDuplicatedException.java @@ -0,0 +1,8 @@ +package com.example.demo.AOPexception.Exception; + +public class PutDuplicatedException extends RuntimeException{ + public PutDuplicatedException(String msg) + { + super(msg); + } +} diff --git a/src/main/java/com/example/demo/AOPexception/Exception/PutNotFoundException.java b/src/main/java/com/example/demo/AOPexception/Exception/PutNotFoundException.java new file mode 100644 index 0000000..06f910a --- /dev/null +++ b/src/main/java/com/example/demo/AOPexception/Exception/PutNotFoundException.java @@ -0,0 +1,8 @@ +package com.example.demo.AOPexception.Exception; + +public class PutNotFoundException extends RuntimeException{ + public PutNotFoundException(String msg) + { + super(msg); + } +} diff --git a/src/main/java/com/example/demo/repository/ArticleRepository.java b/src/main/java/com/example/demo/repository/ArticleRepository.java index 3ef9445..be3ebd4 100644 --- a/src/main/java/com/example/demo/repository/ArticleRepository.java +++ b/src/main/java/com/example/demo/repository/ArticleRepository.java @@ -10,6 +10,8 @@ public interface ArticleRepository { List
findAllByBoardId(Long boardId); + List
findAllByMemberId(Long memberId); + Article findById(Long id); Article insert(Article article); diff --git a/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java b/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java index 349daf4..16895f4 100644 --- a/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java @@ -21,39 +21,60 @@ public ArticleRepositoryJdbc(JdbcTemplate jdbcTemplate) { } private static final RowMapper
articleRowMapper = (rs, rowNum) -> new Article( - rs.getLong("id"), - rs.getLong("author_id"), - rs.getLong("board_id"), - rs.getString("title"), - rs.getString("content"), - rs.getTimestamp("created_date").toLocalDateTime(), - rs.getTimestamp("modified_date").toLocalDateTime() + rs.getLong("id"), + rs.getLong("author_id"), + rs.getLong("board_id"), + rs.getString("title"), + rs.getString("content"), + rs.getTimestamp("created_date").toLocalDateTime(), + rs.getTimestamp("modified_date").toLocalDateTime() ); @Override public List
findAll() { return jdbcTemplate.query(""" - SELECT id, board_id, author_id, title, content, created_date, modified_date - FROM article - """, articleRowMapper); + SELECT id, board_id, author_id, title, content, created_date, modified_date + FROM article + """, articleRowMapper); } @Override public List
findAllByBoardId(Long boardId) { - return jdbcTemplate.query(""" - SELECT id, board_id, author_id, title, content, created_date, modified_date - FROM article - WHERE board_id = ? - """, articleRowMapper, boardId); + try { + return jdbcTemplate.query(""" + SELECT id, board_id, author_id, title, content, created_date, modified_date + FROM article + WHERE board_id = ? + """, articleRowMapper, boardId); + } catch (Exception e) { + throw new RuntimeException("Article not found"); + } + } + @Override + public List
findAllByMemberId(Long memberId) { + try { + return jdbcTemplate.query(""" + SELECT id, board_id, author_id, title, content, created_date, modified_date + FROM article + WHERE author_id = ? + """, articleRowMapper, memberId); + } catch (Exception e) { + throw new RuntimeException("Article not found"); + } } @Override public Article findById(Long id) { - return jdbcTemplate.queryForObject(""" - SELECT id, board_id, author_id, title, content, created_date, modified_date - FROM article - WHERE id = ? - """, articleRowMapper, id); + try { + return jdbcTemplate.queryForObject(""" + + SELECT id, board_id, author_id, title, content, created_date, modified_date + FROM article + WHERE id = ? + """, articleRowMapper, id); + } catch (Exception e) { + throw new RuntimeException("Article not found"); + } } @Override @@ -61,10 +82,10 @@ public Article insert(Article article) { KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(con -> { PreparedStatement ps = con.prepareStatement(""" - INSERT INTO article (board_id, author_id, title, content) - VALUES (?, ?, ?, ?) - """, - new String[]{"id"}); + INSERT INTO article (board_id, author_id, title, content) + VALUES (?, ?, ?, ?) + """, + new String[]{"id"}); ps.setLong(1, article.getBoardId()); ps.setLong(2, article.getAuthorId()); ps.setString(3, article.getTitle()); @@ -77,14 +98,14 @@ INSERT INTO article (board_id, author_id, title, content) @Override public Article update(Article article) { jdbcTemplate.update(""" - UPDATE article - SET board_id = ?, title = ?, content = ? - WHERE id = ? - """, - article.getBoardId(), - article.getTitle(), - article.getContent(), - article.getId() + UPDATE article + SET board_id = ?, title = ?, content = ? + WHERE id = ? + """, + article.getBoardId(), + article.getTitle(), + article.getContent(), + article.getId() ); return findById(article.getId()); } @@ -92,8 +113,8 @@ public Article update(Article article) { @Override public void deleteById(Long id) { jdbcTemplate.update(""" - DELETE FROM article - WHERE id = ? - """, id); + DELETE FROM article + WHERE id = ? + """, id); } } diff --git a/src/main/java/com/example/demo/repository/ArticleRepositoryMemory.java b/src/main/java/com/example/demo/repository/ArticleRepositoryMemory.java deleted file mode 100644 index 00d97ca..0000000 --- a/src/main/java/com/example/demo/repository/ArticleRepositoryMemory.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.example.demo.repository; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicLong; - -import com.example.demo.domain.Article; - -public class ArticleRepositoryMemory implements ArticleRepository { - - private static final Map articles = new HashMap<>(); - private static final AtomicLong autoincrement = new AtomicLong(1); - - @Override - public List
findAll() { - return articles.entrySet().stream() - .map(it -> { - Article article = it.getValue(); - article.setId(it.getKey()); - return article; - }).toList(); - } - - @Override - public List
findAllByBoardId(Long boardId) { - return articles.entrySet().stream() - .filter(it -> it.getValue().getBoardId().equals(boardId)) - .map(it -> { - Article article = it.getValue(); - article.setId(it.getKey()); - return article; - }).toList(); - } - - @Override - public Article findById(Long id) { - return articles.getOrDefault(id, null); - } - - @Override - public Article insert(Article article) { - long id = autoincrement.getAndIncrement(); - articles.put(id, article); - article.setId(id); - return article; - } - - @Override - public Article update(Article article) { - articles.put(article.getId(), article); - return article; - } - - @Override - 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..2f3e465 100644 --- a/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java @@ -35,11 +35,16 @@ public List findAll() { @Override public Board findById(Long id) { - return jdbcTemplate.queryForObject(""" - SELECT id, name + try { + return jdbcTemplate.queryForObject(""" + + SELECT id, name FROM board WHERE id = ? """, boardRowMapper, id); + } catch (Exception e) { + throw new RuntimeException("Board not found"); + } } @Override diff --git a/src/main/java/com/example/demo/repository/BoardRepositoryMemory.java b/src/main/java/com/example/demo/repository/BoardRepositoryMemory.java deleted file mode 100644 index 8cf5ecf..0000000 --- a/src/main/java/com/example/demo/repository/BoardRepositoryMemory.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.example.demo.repository; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicLong; - -import com.example.demo.domain.Board; - -public class BoardRepositoryMemory implements BoardRepository { - - private static final Map boards = new HashMap<>(); - private static final AtomicLong autoincrement = new AtomicLong(1); - - static { - // 1번 게시판을 미리 만들어둔다. - boards.put(autoincrement.getAndIncrement(), new Board("자유게시판")); - } - - @Override - public List findAll() { - return boards.entrySet().stream() - .map(it -> { - Board board = it.getValue(); - board.setId(it.getKey()); - return board; - }).toList(); - } - - @Override - public Board findById(Long id) { - return boards.getOrDefault(id, null); - } - - @Override - public Board insert(Board board) { - boards.put(autoincrement.getAndIncrement(), board); - return board; - } - - @Override - public void deleteById(Long id) { - boards.remove(id); - } - - @Override - public Board update(Board board) { - return boards.put(board.getId(), board); - } -} diff --git a/src/main/java/com/example/demo/repository/MemberRepository.java b/src/main/java/com/example/demo/repository/MemberRepository.java index 8e2ad14..597a064 100644 --- a/src/main/java/com/example/demo/repository/MemberRepository.java +++ b/src/main/java/com/example/demo/repository/MemberRepository.java @@ -10,6 +10,8 @@ public interface MemberRepository { Member findById(Long id); + Member findByEmail(String email); + Member insert(Member member); Member update(Member member); diff --git a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java index 30d2262..86aa6bf 100644 --- a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java @@ -21,27 +21,46 @@ 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); + try { + return jdbcTemplate.queryForObject(""" + + SELECT id, name, email, password + FROM member + WHERE id = ? + """, memberRowMapper, id); + } catch (Exception e) { + throw new RuntimeException("Member not found"); + } + } + + @Override + public Member findByEmail(String email) { + try { + return jdbcTemplate.queryForObject(""" + + SELECT id, name, email, password + FROM member + WHERE email = ? + """, memberRowMapper, email); + } catch (Exception e) { + throw new RuntimeException("Member not found"); + } } @Override @@ -49,8 +68,8 @@ 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"}); + 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()); @@ -62,18 +81,18 @@ INSERT INTO member (name, email, password) VALUES (?, ?, ?) @Override public Member update(Member member) { jdbcTemplate.update(""" - UPDATE member - SET name = ?, email = ? - WHERE id = ? - """, member.getName(), member.getEmail(), member.getId()); + UPDATE member + SET name = ?, email = ? + WHERE id = ? + """, member.getName(), member.getEmail(), member.getId()); return findById(member.getId()); } @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/repository/MemberRepositoryMemory.java b/src/main/java/com/example/demo/repository/MemberRepositoryMemory.java deleted file mode 100644 index b4cf722..0000000 --- a/src/main/java/com/example/demo/repository/MemberRepositoryMemory.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.example.demo.repository; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicLong; - -import com.example.demo.domain.Member; - -public class MemberRepositoryMemory implements MemberRepository { - - private static final Map members = new HashMap<>(); - private static final AtomicLong autoincrement = new AtomicLong(1); - - static { - // 1번 유저를 미리 만들어둔다. - members.put(autoincrement.getAndIncrement(), new Member("최준호", "temp@gmail.com", "password")); - } - - @Override - public List findAll() { - return members.entrySet().stream() - .map(it -> { - Member member = it.getValue(); - member.setId(it.getKey()); - return member; - }).toList(); - } - - @Override - public Member findById(Long id) { - return members.getOrDefault(id, null); - } - - @Override - public Member insert(Member member) { - long id = autoincrement.getAndIncrement(); - members.put(id, member); - member.setId(id); - return member; - } - - @Override - public Member update(Member member) { - return members.put(member.getId(), member); - } - - @Override - 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 7f8610b..956cc92 100644 --- a/src/main/java/com/example/demo/service/ArticleService.java +++ b/src/main/java/com/example/demo/service/ArticleService.java @@ -2,6 +2,10 @@ import java.util.List; +import com.example.demo.AOPexception.Exception.GetNotFoundException; +import com.example.demo.AOPexception.Exception.PostIllegalArgumemtException; +import com.example.demo.AOPexception.Exception.PostNotFoundException; +import com.example.demo.AOPexception.Exception.PutNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,9 +28,9 @@ public class ArticleService { private final BoardRepository boardRepository; public ArticleService( - ArticleRepository articleRepository, - MemberRepository memberRepository, - BoardRepository boardRepository + ArticleRepository articleRepository, + MemberRepository memberRepository, + BoardRepository boardRepository ) { this.articleRepository = articleRepository; this.memberRepository = memberRepository; @@ -34,45 +38,65 @@ 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 GetNotFoundException(e.getMessage()); + } } 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); - }) - .toList(); + try { + 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); + }) + .toList(); + } catch (RuntimeException e) { + throw new GetNotFoundException(e.getMessage()); + } } @Transactional public ArticleResponse create(ArticleCreateRequest request) { Article article = new Article( - request.authorId(), - request.boardId(), - request.title(), - request.description() + request.authorId(), + request.boardId(), + request.title(), + request.description() ); + if (article.getAuthorId() == null || article.getBoardId() == null || + article.getTitle() == null || article.getContent() == null) { + throw new PostIllegalArgumemtException("NULL field existed"); + } Article saved = articleRepository.insert(article); - Member member = memberRepository.findById(saved.getAuthorId()); - Board board = boardRepository.findById(saved.getBoardId()); - return ArticleResponse.of(saved, member, board); + try { + Member member = memberRepository.findById(saved.getAuthorId()); + Board board = boardRepository.findById(saved.getBoardId()); + return ArticleResponse.of(saved, member, board); + } catch (RuntimeException e) { + throw new PostNotFoundException(e.getMessage()); + } } @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(updated.getAuthorId()); - Board board = boardRepository.findById(article.getBoardId()); - return ArticleResponse.of(article, member, board); + try { + 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()); + return ArticleResponse.of(article, member, board); + } catch (RuntimeException e) { + throw new PutNotFoundException(e.getMessage()); + } } @Transactional diff --git a/src/main/java/com/example/demo/service/BoardService.java b/src/main/java/com/example/demo/service/BoardService.java index ffff891..1628f94 100644 --- a/src/main/java/com/example/demo/service/BoardService.java +++ b/src/main/java/com/example/demo/service/BoardService.java @@ -2,6 +2,10 @@ import java.util.List; +import com.example.demo.AOPexception.Exception.DeleteExistedExcepton; +import com.example.demo.AOPexception.Exception.GetNotFoundException; +import com.example.demo.repository.ArticleRepository; +import com.example.demo.repository.ArticleRepositoryJdbc; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,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() { @@ -28,8 +34,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 GetNotFoundException(e.getMessage()); + } } @Transactional @@ -41,6 +51,8 @@ public BoardResponse createBoard(BoardCreateRequest request) { @Transactional public void deleteBoard(Long id) { + if(!articleRepository.findAllByBoardId(id).isEmpty()) + throw new DeleteExistedExcepton("Articles 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 04c1bc8..5e5e593 100644 --- a/src/main/java/com/example/demo/service/MemberService.java +++ b/src/main/java/com/example/demo/service/MemberService.java @@ -2,6 +2,10 @@ import java.util.List; +import com.example.demo.AOPexception.Exception.DeleteExistedExcepton; +import com.example.demo.AOPexception.Exception.GetNotFoundException; +import com.example.demo.AOPexception.Exception.PutDuplicatedException; +import com.example.demo.repository.ArticleRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,41 +20,54 @@ public class MemberService { private final MemberRepository memberRepository; + public final ArticleRepository articleRepository; - public MemberService(MemberRepository memberRepository) { + public MemberService(MemberRepository memberRepository, ArticleRepository articleRepository) { this.memberRepository = memberRepository; + this.articleRepository = articleRepository; } 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 GetNotFoundException(e.getMessage()); + } } public List getAll() { List members = memberRepository.findAll(); return members.stream() - .map(MemberResponse::from) - .toList(); + .map(MemberResponse::from) + .toList(); } @Transactional public MemberResponse create(MemberCreateRequest request) { Member member = memberRepository.insert( - new Member(request.name(), request.email(), request.password()) + new Member(request.name(), request.email(), request.password()) ); return MemberResponse.from(member); } @Transactional public void delete(Long id) { - memberRepository.deleteById(id); + if (!articleRepository.findAllByMemberId(id).isEmpty()) + throw new DeleteExistedExcepton("one above articles existed written by this member"); + memberRepository.deleteById(id); } @Transactional public MemberResponse update(Long id, MemberUpdateRequest request) { Member member = memberRepository.findById(id); - member.update(request.name(), request.email()); - memberRepository.update(member); - return MemberResponse.from(member); + try { + memberRepository.findByEmail(request.email()); + } catch (RuntimeException e) { + member.update(request.name(), request.email()); + memberRepository.update(member); + return MemberResponse.from(member); + } + throw new PutDuplicatedException("already used email"); } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ff69a9e..cf86041 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: gkrdlsdlelql!! # 본인의 환경에 맞게 수정한다. driver-class-name: com.mysql.cj.jdbc.Driver From 35b2d5014193af688d22049504f7ca3cefb682d2 Mon Sep 17 00:00:00 2001 From: FrozenInclude Date: Tue, 4 Jun 2024 11:23:24 +0900 Subject: [PATCH 3/8] fix bug --- .../java/com/example/demo/service/ArticleService.java | 10 +++++----- .../java/com/example/demo/service/BoardService.java | 4 ++++ .../java/com/example/demo/service/MemberService.java | 6 +++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/example/demo/service/ArticleService.java b/src/main/java/com/example/demo/service/ArticleService.java index 956cc92..057a072 100644 --- a/src/main/java/com/example/demo/service/ArticleService.java +++ b/src/main/java/com/example/demo/service/ArticleService.java @@ -75,10 +75,10 @@ public ArticleResponse create(ArticleCreateRequest request) { article.getTitle() == null || article.getContent() == null) { throw new PostIllegalArgumemtException("NULL field existed"); } - Article saved = articleRepository.insert(article); - try { - Member member = memberRepository.findById(saved.getAuthorId()); - Board board = boardRepository.findById(saved.getBoardId()); + try{ + Member member = memberRepository.findById(article.getAuthorId()); + Board board = boardRepository.findById(article.getBoardId()); + Article saved = articleRepository.insert(article); return ArticleResponse.of(saved, member, board); } catch (RuntimeException e) { throw new PostNotFoundException(e.getMessage()); @@ -89,10 +89,10 @@ public ArticleResponse create(ArticleCreateRequest request) { public ArticleResponse update(Long id, ArticleUpdateRequest request) { try { Article article = articleRepository.findById(id); + Board board = boardRepository.findById(request.boardId()); 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()); return ArticleResponse.of(article, member, board); } catch (RuntimeException e) { throw new PutNotFoundException(e.getMessage()); diff --git a/src/main/java/com/example/demo/service/BoardService.java b/src/main/java/com/example/demo/service/BoardService.java index 1628f94..4a04945 100644 --- a/src/main/java/com/example/demo/service/BoardService.java +++ b/src/main/java/com/example/demo/service/BoardService.java @@ -4,6 +4,7 @@ import com.example.demo.AOPexception.Exception.DeleteExistedExcepton; import com.example.demo.AOPexception.Exception.GetNotFoundException; +import com.example.demo.AOPexception.Exception.PostIllegalArgumemtException; import com.example.demo.repository.ArticleRepository; import com.example.demo.repository.ArticleRepositoryJdbc; import org.springframework.stereotype.Service; @@ -44,6 +45,9 @@ public BoardResponse getBoardById(Long id) { @Transactional public BoardResponse createBoard(BoardCreateRequest request) { + if (request.name() == null ) { + throw new PostIllegalArgumemtException("NULL field existed"); + } Board board = new Board(request.name()); Board saved = boardRepository.insert(board); return BoardResponse.from(saved); diff --git a/src/main/java/com/example/demo/service/MemberService.java b/src/main/java/com/example/demo/service/MemberService.java index 5e5e593..75c0c79 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.AOPexception.Exception.DeleteExistedExcepton; import com.example.demo.AOPexception.Exception.GetNotFoundException; +import com.example.demo.AOPexception.Exception.PostIllegalArgumemtException; import com.example.demo.AOPexception.Exception.PutDuplicatedException; import com.example.demo.repository.ArticleRepository; import org.springframework.stereotype.Service; @@ -45,6 +46,9 @@ public List getAll() { @Transactional public MemberResponse create(MemberCreateRequest request) { + if (request.name() == null || request.email() == null || request.password() == null) { + throw new PostIllegalArgumemtException("NULL field existed"); + } Member member = memberRepository.insert( new Member(request.name(), request.email(), request.password()) ); @@ -55,7 +59,7 @@ public MemberResponse create(MemberCreateRequest request) { public void delete(Long id) { if (!articleRepository.findAllByMemberId(id).isEmpty()) throw new DeleteExistedExcepton("one above articles existed written by this member"); - memberRepository.deleteById(id); + memberRepository.deleteById(id); } @Transactional From 90d71145b9a90cee54422bf530acb8b161709224 Mon Sep 17 00:00:00 2001 From: FrozenInclude Date: Tue, 25 Jun 2024 14:18:03 +0900 Subject: [PATCH 4/8] implement Jpa --- build.gradle | 2 + .../demo/AOPexception/ExceptHandler.java | 2 +- .../com/example/demo/DemoApplication.java | 2 + .../java/com/example/demo/domain/Article.java | 17 ++++- .../java/com/example/demo/domain/Board.java | 11 ++- .../java/com/example/demo/domain/Member.java | 11 ++- .../repository/ArticleRepositoryJdbc.java | 1 - .../demo/repository/ArticleRepositoryJpa.java | 69 +++++++++++++++++++ .../demo/repository/BoardRepositoryJdbc.java | 1 - .../demo/repository/BoardRepositoryJpa.java | 48 +++++++++++++ .../demo/repository/MemberRepositoryJdbc.java | 1 - .../demo/repository/MemberRepositoryJpa.java | 58 ++++++++++++++++ src/main/resources/application.yml | 12 ++-- 13 files changed, 222 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java 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 728ec9c..b158065 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,8 @@ 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' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0' runtimeOnly 'com.mysql:mysql-connector-j' testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/com/example/demo/AOPexception/ExceptHandler.java b/src/main/java/com/example/demo/AOPexception/ExceptHandler.java index fdd2750..4fdf932 100644 --- a/src/main/java/com/example/demo/AOPexception/ExceptHandler.java +++ b/src/main/java/com/example/demo/AOPexception/ExceptHandler.java @@ -2,11 +2,11 @@ import com.example.demo.AOPexception.Exception.*; import org.apache.coyote.BadRequestException; +import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; - @RestControllerAdvice public class ExceptHandler { @ExceptionHandler diff --git a/src/main/java/com/example/demo/DemoApplication.java b/src/main/java/com/example/demo/DemoApplication.java index 094d95b..23607a4 100644 --- a/src/main/java/com/example/demo/DemoApplication.java +++ b/src/main/java/com/example/demo/DemoApplication.java @@ -2,7 +2,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +@EnableAspectJAutoProxy @SpringBootApplication public class DemoApplication { diff --git a/src/main/java/com/example/demo/domain/Article.java b/src/main/java/com/example/demo/domain/Article.java index e0183db..ec19e95 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 java.time.LocalDateTime; +import jakarta.persistence.*; +import java.time.LocalDateTime; +@Entity +@Table(name = "article") public class Article { - + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(name = "author_id") private Long authorId; + @Column(name = "board_id") private Long boardId; private String title; private String content; + @Column(name = "created_date") private LocalDateTime createdAt; + @Column(name = "modified_date") private LocalDateTime modifiedAt; public Article( @@ -40,6 +48,11 @@ 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/domain/Board.java b/src/main/java/com/example/demo/domain/Board.java index 992e2c6..d5fdb72 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; -public class Board { +import jakarta.persistence.*; +@Entity +@Table(name = "board") +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 fe80d6b..fa834a5 100644 --- a/src/main/java/com/example/demo/domain/Member.java +++ b/src/main/java/com/example/demo/domain/Member.java @@ -1,7 +1,12 @@ package com.example.demo.domain; -public class Member { +import jakarta.persistence.*; +@Entity +@Table(name = "member") +public class Member { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; @@ -20,6 +25,10 @@ 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/ArticleRepositoryJdbc.java b/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java index 16895f4..a9d12c4 100644 --- a/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java @@ -11,7 +11,6 @@ import com.example.demo.domain.Article; -@Repository public class ArticleRepositoryJdbc implements ArticleRepository { private final JdbcTemplate jdbcTemplate; 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..b4bab0e --- /dev/null +++ b/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java @@ -0,0 +1,69 @@ +package com.example.demo.repository; + + +import com.example.demo.domain.Article; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class ArticleRepositoryJpa implements ArticleRepository { + @PersistenceContext + private EntityManager entityManager; + + + @Override + public List
findAll() { + return entityManager.createQuery("SELECT e FROM Article e", Article.class).getResultList(); + } + + @Override + public List
findAllByBoardId(Long boardId) { + try { + return entityManager.createQuery("SELECT e FROM Article e WHERE e.boardId=:boardId", Article.class). + setParameter("boardId", boardId).getResultList(); + } catch (Exception e) { + throw new RuntimeException("Article not found"); + } + } + + @Override + public List
findAllByMemberId(Long memberId) { + try { + return entityManager.createQuery("SELECT e FROM Article e WHERE e.authorId=:memberId", Article.class) + .setParameter("memberId", memberId).getResultList(); + } catch (Exception e) { + throw new RuntimeException("Article not found"); + } + } + + @Override + public Article findById(Long id) { + try { + return entityManager.find(Article.class, id); + } catch (Exception e) { + throw new RuntimeException("Article not found"); + } + } + + @Override + public Article insert(Article article) { + entityManager.persist(article); + return entityManager.find(Article.class, article.getId()); + } + + @Override + public Article update(Article article) { + Article art = findById(article.getId()); + art.update(article.getBoardId(), article.getTitle(), article.getContent()); + return art; + } + + @Override + public void deleteById(Long id) { + Article article = findById(id); + entityManager.remove(article); + } +} diff --git a/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java b/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java index 2f3e465..e96488a 100644 --- a/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java @@ -11,7 +11,6 @@ import com.example.demo.domain.Board; -@Repository public class BoardRepositoryJdbc implements BoardRepository { private final JdbcTemplate jdbcTemplate; 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..ea4cd77 --- /dev/null +++ b/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java @@ -0,0 +1,48 @@ +package com.example.demo.repository; + +import com.example.demo.domain.Board; +import com.example.demo.domain.Member; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class BoardRepositoryJpa implements BoardRepository { + @PersistenceContext + private EntityManager entityManager; + + @Override + public List findAll() { + return entityManager.createQuery("SELECT e FROM Board e", Board.class).getResultList(); + } + + @Override + public Board findById(Long id) { + try { + return entityManager.find(Board.class, id); + } catch (Exception e) { + throw new RuntimeException("Board not found"); + } + } + + @Override + public Board insert(Board board) { + entityManager.persist(board); + return entityManager.find(Board.class, board.getId()); + } + + @Override + public void deleteById(Long id) { + Board board = findById(id); + entityManager.remove(board); + } + + @Override + public Board update(Board board) { + Board brd = findById(board.getId()); + brd.update(board.getName()); + return brd; + } +} diff --git a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java index 86aa6bf..8ec401b 100644 --- a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java +++ b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java @@ -11,7 +11,6 @@ import com.example.demo.domain.Member; -@Repository public class MemberRepositoryJdbc implements MemberRepository { private final JdbcTemplate jdbcTemplate; 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..4ddece4 --- /dev/null +++ b/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java @@ -0,0 +1,58 @@ +package com.example.demo.repository; + +import com.example.demo.domain.Member; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class MemberRepositoryJpa implements MemberRepository { + + @PersistenceContext + private EntityManager entityManager; + + @Override + public List findAll() { + return entityManager.createQuery("SELECT e FROM Member e", Member.class).getResultList(); + } + + @Override + public Member findById(Long id) { + try { + return entityManager.find(Member.class, id); + } catch (Exception e) { + throw new RuntimeException("Member not found"); + } + } + + @Override + public Member findByEmail(String email) { + try { + return entityManager.createQuery("SELECT e FROM Member e WHERE e.email=:email", Member.class). + setParameter("email", email).getSingleResult(); + } catch (Exception e) { + throw new RuntimeException("Member not found"); + } + } + + @Override + public Member insert(Member member) { + entityManager.persist(member); + return entityManager.find(Member.class, member.getId()); + } + + @Override + public Member update(Member member) { + Member mem = findById(member.getId()); + mem.update(member.getName(), member.getEmail()); + return mem; + } + + @Override + public void deleteById(Long id) { + Member member = findById(id); + entityManager.remove(member); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index cf86041..49c4ab0 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,8 @@ spring: - datasource: - url: jdbc:mysql://localhost:3306/bcsd # 본인의 환경에 맞게 수정한다. - username: root # 본인의 환경에 맞게 수정한다. - password: gkrdlsdlelql!! # 본인의 환경에 맞게 수정한다. - driver-class-name: com.mysql.cj.jdbc.Driver + jpa: + show-sql: true + datasource: + url: jdbc:mysql://localhost:3306/bcsd # 본인의 환경에 맞게 수정한다. + driver-class-name: com.mysql.cj.jdbc.Driver + username: root # 본인의 환경에 맞게 수정한다. + password: gkrdlsdlelql!! # 본인의 환경에 맞게 수정한다. From 064bf471c0374a724737e8ff2f5201f60b515ac0 Mon Sep 17 00:00:00 2001 From: FrozenInclude Date: Tue, 2 Jul 2024 16:22:15 +0900 Subject: [PATCH 5/8] =?UTF-8?q?=EC=97=B0=EA=B4=80=EA=B4=80=EA=B3=84=20?= =?UTF-8?q?=EB=A7=A4=ED=95=91,=EC=9D=98=EC=A1=B4=EC=84=B1=EC=A0=84?= =?UTF-8?q?=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/demo/domain/Article.java | 21 ++-- .../java/com/example/demo/domain/Board.java | 5 + .../demo/repository/ArticleRepository.java | 18 +-- .../repository/ArticleRepositoryJdbc.java | 119 ------------------ .../demo/repository/ArticleRepositoryJpa.java | 69 ---------- .../demo/repository/BoardRepository.java | 13 +- .../demo/repository/BoardRepositoryJdbc.java | 76 ----------- .../demo/repository/BoardRepositoryJpa.java | 48 ------- .../demo/repository/MemberRepository.java | 14 +-- .../demo/repository/MemberRepositoryJdbc.java | 97 -------------- .../demo/repository/MemberRepositoryJpa.java | 58 --------- .../example/demo/service/ArticleService.java | 52 +++++--- .../example/demo/service/BoardService.java | 13 +- .../example/demo/service/MemberService.java | 10 +- 14 files changed, 73 insertions(+), 540 deletions(-) delete mode 100644 src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java delete mode 100644 src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java delete mode 100644 src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java delete mode 100644 src/main/java/com/example/demo/repository/BoardRepositoryJpa.java delete mode 100644 src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java delete mode 100644 src/main/java/com/example/demo/repository/MemberRepositoryJpa.java diff --git a/src/main/java/com/example/demo/domain/Article.java b/src/main/java/com/example/demo/domain/Article.java index ec19e95..c1a9714 100644 --- a/src/main/java/com/example/demo/domain/Article.java +++ b/src/main/java/com/example/demo/domain/Article.java @@ -11,8 +11,11 @@ public class Article { private Long id; @Column(name = "author_id") private Long authorId; - @Column(name = "board_id") - private Long boardId; + + @ManyToOne + @JoinColumn(name="board_id") + private Board board; + private String title; private String content; @Column(name = "created_date") @@ -23,7 +26,7 @@ public class Article { public Article( Long id, Long authorId, - Long boardId, + Board board, String title, String content, LocalDateTime createdAt, @@ -31,17 +34,17 @@ public Article( ) { this.id = id; this.authorId = authorId; - this.boardId = boardId; + this.board = board; this.title = title; this.content = content; this.createdAt = createdAt; this.modifiedAt = modifiedAt; } - public Article(Long authorId, Long boardId, String title, String content) { + public Article(Long authorId, Board board, String title, String content) { this.id = null; this.authorId = authorId; - this.boardId = boardId; + this.board = board; this.title = title; this.content = content; this.createdAt = LocalDateTime.now(); @@ -53,8 +56,8 @@ 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(); @@ -77,7 +80,7 @@ public Long getAuthorId() { } public Long getBoardId() { - return boardId; + return board.getId(); } public String getTitle() { diff --git a/src/main/java/com/example/demo/domain/Board.java b/src/main/java/com/example/demo/domain/Board.java index d5fdb72..ac46fa0 100644 --- a/src/main/java/com/example/demo/domain/Board.java +++ b/src/main/java/com/example/demo/domain/Board.java @@ -2,6 +2,8 @@ import jakarta.persistence.*; +import java.util.List; + @Entity @Table(name = "board") public class Board { @@ -9,6 +11,8 @@ public class Board { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; + @OneToMany(mappedBy = "board",cascade = CascadeType.ALL, orphanRemoval = true) + private List
articles; public Board(Long id, String name) { this.id = id; @@ -38,4 +42,5 @@ public String getName() { public void update(String name) { this.name = name; } + } diff --git a/src/main/java/com/example/demo/repository/ArticleRepository.java b/src/main/java/com/example/demo/repository/ArticleRepository.java index be3ebd4..daff8ee 100644 --- a/src/main/java/com/example/demo/repository/ArticleRepository.java +++ b/src/main/java/com/example/demo/repository/ArticleRepository.java @@ -3,20 +3,10 @@ import java.util.List; import com.example.demo.domain.Article; +import org.springframework.data.jpa.repository.JpaRepository; -public interface ArticleRepository { +public interface ArticleRepository extends JpaRepository { + List
findAllByBoard_Id(Long boardId); - 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); + List
findAllByAuthorId(Long memberId); } diff --git a/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java b/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java deleted file mode 100644 index a9d12c4..0000000 --- a/src/main/java/com/example/demo/repository/ArticleRepositoryJdbc.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.example.demo.repository; - -import java.sql.PreparedStatement; -import java.util.List; - -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.springframework.jdbc.support.KeyHolder; -import org.springframework.stereotype.Repository; - -import com.example.demo.domain.Article; - -public class ArticleRepositoryJdbc implements ArticleRepository { - - private final JdbcTemplate jdbcTemplate; - - public ArticleRepositoryJdbc(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - private static final RowMapper
articleRowMapper = (rs, rowNum) -> new Article( - rs.getLong("id"), - rs.getLong("author_id"), - rs.getLong("board_id"), - rs.getString("title"), - rs.getString("content"), - rs.getTimestamp("created_date").toLocalDateTime(), - rs.getTimestamp("modified_date").toLocalDateTime() - ); - - @Override - public List
findAll() { - return jdbcTemplate.query(""" - SELECT id, board_id, author_id, title, content, created_date, modified_date - FROM article - """, articleRowMapper); - } - - @Override - public List
findAllByBoardId(Long boardId) { - try { - return jdbcTemplate.query(""" - SELECT id, board_id, author_id, title, content, created_date, modified_date - FROM article - WHERE board_id = ? - """, articleRowMapper, boardId); - } catch (Exception e) { - throw new RuntimeException("Article not found"); - } - } - @Override - public List
findAllByMemberId(Long memberId) { - try { - return jdbcTemplate.query(""" - SELECT id, board_id, author_id, title, content, created_date, modified_date - FROM article - WHERE author_id = ? - """, articleRowMapper, memberId); - } catch (Exception e) { - throw new RuntimeException("Article not found"); - } - } - - @Override - public Article findById(Long id) { - try { - return jdbcTemplate.queryForObject(""" - - SELECT id, board_id, author_id, title, content, created_date, modified_date - FROM article - WHERE id = ? - """, articleRowMapper, id); - } catch (Exception e) { - throw new RuntimeException("Article not found"); - } - } - - @Override - public Article insert(Article article) { - KeyHolder keyHolder = new GeneratedKeyHolder(); - jdbcTemplate.update(con -> { - PreparedStatement ps = con.prepareStatement(""" - INSERT INTO article (board_id, author_id, title, content) - VALUES (?, ?, ?, ?) - """, - new String[]{"id"}); - ps.setLong(1, article.getBoardId()); - ps.setLong(2, article.getAuthorId()); - ps.setString(3, article.getTitle()); - ps.setString(4, article.getContent()); - return ps; - }, keyHolder); - return findById(keyHolder.getKey().longValue()); - } - - @Override - public Article update(Article article) { - jdbcTemplate.update(""" - UPDATE article - SET board_id = ?, title = ?, content = ? - WHERE id = ? - """, - article.getBoardId(), - article.getTitle(), - article.getContent(), - article.getId() - ); - return findById(article.getId()); - } - - @Override - public void deleteById(Long id) { - jdbcTemplate.update(""" - DELETE FROM article - WHERE id = ? - """, id); - } -} diff --git a/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java b/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java deleted file mode 100644 index b4bab0e..0000000 --- a/src/main/java/com/example/demo/repository/ArticleRepositoryJpa.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.example.demo.repository; - - -import com.example.demo.domain.Article; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public class ArticleRepositoryJpa implements ArticleRepository { - @PersistenceContext - private EntityManager entityManager; - - - @Override - public List
findAll() { - return entityManager.createQuery("SELECT e FROM Article e", Article.class).getResultList(); - } - - @Override - public List
findAllByBoardId(Long boardId) { - try { - return entityManager.createQuery("SELECT e FROM Article e WHERE e.boardId=:boardId", Article.class). - setParameter("boardId", boardId).getResultList(); - } catch (Exception e) { - throw new RuntimeException("Article not found"); - } - } - - @Override - public List
findAllByMemberId(Long memberId) { - try { - return entityManager.createQuery("SELECT e FROM Article e WHERE e.authorId=:memberId", Article.class) - .setParameter("memberId", memberId).getResultList(); - } catch (Exception e) { - throw new RuntimeException("Article not found"); - } - } - - @Override - public Article findById(Long id) { - try { - return entityManager.find(Article.class, id); - } catch (Exception e) { - throw new RuntimeException("Article not found"); - } - } - - @Override - public Article insert(Article article) { - entityManager.persist(article); - return entityManager.find(Article.class, article.getId()); - } - - @Override - public Article update(Article article) { - Article art = findById(article.getId()); - art.update(article.getBoardId(), article.getTitle(), article.getContent()); - return art; - } - - @Override - public void deleteById(Long id) { - Article article = findById(id); - entityManager.remove(article); - } -} diff --git a/src/main/java/com/example/demo/repository/BoardRepository.java b/src/main/java/com/example/demo/repository/BoardRepository.java index cc2dfd0..5124fba 100644 --- a/src/main/java/com/example/demo/repository/BoardRepository.java +++ b/src/main/java/com/example/demo/repository/BoardRepository.java @@ -2,17 +2,10 @@ import java.util.List; +import com.example.demo.domain.Article; import com.example.demo.domain.Board; +import org.springframework.data.jpa.repository.JpaRepository; -public interface BoardRepository { +public interface BoardRepository extends JpaRepository { - List findAll(); - - Board findById(Long id); - - Board insert(Board board); - - void deleteById(Long id); - - Board update(Board board); } diff --git a/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java b/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java deleted file mode 100644 index e96488a..0000000 --- a/src/main/java/com/example/demo/repository/BoardRepositoryJdbc.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.example.demo.repository; - -import java.sql.PreparedStatement; -import java.util.List; - -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.springframework.jdbc.support.KeyHolder; -import org.springframework.stereotype.Repository; - -import com.example.demo.domain.Board; - -public class BoardRepositoryJdbc implements BoardRepository { - - private final JdbcTemplate jdbcTemplate; - - public BoardRepositoryJdbc(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - private static final RowMapper boardRowMapper = (rs, rowNum) -> new Board( - rs.getLong("id"), - rs.getString("name") - ); - - @Override - public List findAll() { - return jdbcTemplate.query(""" - SELECT id, name - FROM board - """, boardRowMapper); - } - - @Override - public Board findById(Long id) { - try { - return jdbcTemplate.queryForObject(""" - - SELECT id, name - FROM board - WHERE id = ? - """, boardRowMapper, id); - } catch (Exception e) { - throw new RuntimeException("Board not found"); - } - } - - @Override - public Board insert(Board board) { - KeyHolder keyHolder = new GeneratedKeyHolder(); - jdbcTemplate.update(con -> { - PreparedStatement ps = con.prepareStatement(""" - INSERT INTO board (name) VALUES (?) - """, new String[]{"id"}); - ps.setString(1, board.getName()); - return ps; - }, keyHolder); - return findById(keyHolder.getKey().longValue()); - } - - @Override - public void deleteById(Long id) { - jdbcTemplate.update(""" - DELETE FROM board WHERE id = ? - """, id); - } - - @Override - public Board update(Board board) { - return jdbcTemplate.queryForObject(""" - UPDATE board SET name = ? WHERE id = ? - """, boardRowMapper, board.getName(), board.getId() - ); - } -} diff --git a/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java b/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java deleted file mode 100644 index ea4cd77..0000000 --- a/src/main/java/com/example/demo/repository/BoardRepositoryJpa.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.example.demo.repository; - -import com.example.demo.domain.Board; -import com.example.demo.domain.Member; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public class BoardRepositoryJpa implements BoardRepository { - @PersistenceContext - private EntityManager entityManager; - - @Override - public List findAll() { - return entityManager.createQuery("SELECT e FROM Board e", Board.class).getResultList(); - } - - @Override - public Board findById(Long id) { - try { - return entityManager.find(Board.class, id); - } catch (Exception e) { - throw new RuntimeException("Board not found"); - } - } - - @Override - public Board insert(Board board) { - entityManager.persist(board); - return entityManager.find(Board.class, board.getId()); - } - - @Override - public void deleteById(Long id) { - Board board = findById(id); - entityManager.remove(board); - } - - @Override - public Board update(Board board) { - Board brd = findById(board.getId()); - brd.update(board.getName()); - return brd; - } -} diff --git a/src/main/java/com/example/demo/repository/MemberRepository.java b/src/main/java/com/example/demo/repository/MemberRepository.java index 597a064..baad833 100644 --- a/src/main/java/com/example/demo/repository/MemberRepository.java +++ b/src/main/java/com/example/demo/repository/MemberRepository.java @@ -3,18 +3,8 @@ import java.util.List; import com.example.demo.domain.Member; +import org.springframework.data.jpa.repository.JpaRepository; -public interface MemberRepository { - - List findAll(); - - Member findById(Long id); - +public interface MemberRepository extends JpaRepository { Member findByEmail(String email); - - Member insert(Member member); - - Member update(Member member); - - void deleteById(Long id); } diff --git a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java b/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java deleted file mode 100644 index 8ec401b..0000000 --- a/src/main/java/com/example/demo/repository/MemberRepositoryJdbc.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.example.demo.repository; - -import java.sql.PreparedStatement; -import java.util.List; - -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.springframework.jdbc.support.KeyHolder; -import org.springframework.stereotype.Repository; - -import com.example.demo.domain.Member; - -public class MemberRepositoryJdbc implements MemberRepository { - - private final JdbcTemplate jdbcTemplate; - - public MemberRepositoryJdbc(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - private static final RowMapper memberRowMapper = (rs, rowNum) -> new Member( - 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); - } - - @Override - public Member findById(Long id) { - try { - return jdbcTemplate.queryForObject(""" - - SELECT id, name, email, password - FROM member - WHERE id = ? - """, memberRowMapper, id); - } catch (Exception e) { - throw new RuntimeException("Member not found"); - } - } - - @Override - public Member findByEmail(String email) { - try { - return jdbcTemplate.queryForObject(""" - - SELECT id, name, email, password - FROM member - WHERE email = ? - """, memberRowMapper, email); - } catch (Exception e) { - throw new RuntimeException("Member not found"); - } - } - - @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()); - ps.setString(3, member.getPassword()); - return ps; - }, keyHolder); - return findById(keyHolder.getKey().longValue()); - } - - @Override - public Member update(Member member) { - jdbcTemplate.update(""" - UPDATE member - SET name = ?, email = ? - WHERE id = ? - """, member.getName(), member.getEmail(), member.getId()); - return findById(member.getId()); - } - - @Override - public void deleteById(Long id) { - jdbcTemplate.update(""" - DELETE FROM member - WHERE id = ? - """, id); - } -} diff --git a/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java b/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java deleted file mode 100644 index 4ddece4..0000000 --- a/src/main/java/com/example/demo/repository/MemberRepositoryJpa.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.example.demo.repository; - -import com.example.demo.domain.Member; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public class MemberRepositoryJpa implements MemberRepository { - - @PersistenceContext - private EntityManager entityManager; - - @Override - public List findAll() { - return entityManager.createQuery("SELECT e FROM Member e", Member.class).getResultList(); - } - - @Override - public Member findById(Long id) { - try { - return entityManager.find(Member.class, id); - } catch (Exception e) { - throw new RuntimeException("Member not found"); - } - } - - @Override - public Member findByEmail(String email) { - try { - return entityManager.createQuery("SELECT e FROM Member e WHERE e.email=:email", Member.class). - setParameter("email", email).getSingleResult(); - } catch (Exception e) { - throw new RuntimeException("Member not found"); - } - } - - @Override - public Member insert(Member member) { - entityManager.persist(member); - return entityManager.find(Member.class, member.getId()); - } - - @Override - public Member update(Member member) { - Member mem = findById(member.getId()); - mem.update(member.getName(), member.getEmail()); - return mem; - } - - @Override - public void deleteById(Long id) { - Member member = findById(id); - entityManager.remove(member); - } -} diff --git a/src/main/java/com/example/demo/service/ArticleService.java b/src/main/java/com/example/demo/service/ArticleService.java index 057a072..cd3736f 100644 --- a/src/main/java/com/example/demo/service/ArticleService.java +++ b/src/main/java/com/example/demo/service/ArticleService.java @@ -39,9 +39,15 @@ public ArticleService( public ArticleResponse getById(Long id) { try { - Article article = articleRepository.findById(id); - Member member = memberRepository.findById(article.getAuthorId()); - Board board = boardRepository.findById(article.getBoardId()); + Article article = articleRepository.findById(id) + .orElseThrow(IllegalArgumentException::new); + ; + Member member = memberRepository.findById(article.getAuthorId()) + .orElseThrow(IllegalArgumentException::new); + ; + Board board = boardRepository.findById(article.getBoardId()) + .orElseThrow(IllegalArgumentException::new); + ; return ArticleResponse.of(article, member, board); } catch (RuntimeException e) { throw new GetNotFoundException(e.getMessage()); @@ -50,11 +56,15 @@ public ArticleResponse getById(Long id) { public List getByBoardId(Long boardId) { try { - List
articles = articleRepository.findAllByBoardId(boardId); + List
articles = articleRepository.findAllByBoard_Id(boardId); return articles.stream() .map(article -> { - Member member = memberRepository.findById(article.getAuthorId()); - Board board = boardRepository.findById(article.getBoardId()); + Member member = memberRepository.findById(article.getAuthorId()) + .orElseThrow(IllegalArgumentException::new); + ; + Board board = boardRepository.findById(article.getBoardId()) + .orElseThrow(IllegalArgumentException::new); + ; return ArticleResponse.of(article, member, board); }) .toList(); @@ -67,7 +77,7 @@ public List getByBoardId(Long boardId) { public ArticleResponse create(ArticleCreateRequest request) { Article article = new Article( request.authorId(), - request.boardId(), + boardRepository.getReferenceById(request.boardId()), request.title(), request.description() ); @@ -75,10 +85,14 @@ public ArticleResponse create(ArticleCreateRequest request) { article.getTitle() == null || article.getContent() == null) { throw new PostIllegalArgumemtException("NULL field existed"); } - try{ - Member member = memberRepository.findById(article.getAuthorId()); - Board board = boardRepository.findById(article.getBoardId()); - Article saved = articleRepository.insert(article); + try { + Member member = memberRepository.findById(article.getAuthorId()) + .orElseThrow(IllegalArgumentException::new); + ; + Board board = boardRepository.findById(article.getBoardId()) + .orElseThrow(IllegalArgumentException::new); + ; + Article saved = articleRepository.save(article); return ArticleResponse.of(saved, member, board); } catch (RuntimeException e) { throw new PostNotFoundException(e.getMessage()); @@ -88,11 +102,17 @@ public ArticleResponse create(ArticleCreateRequest request) { @Transactional public ArticleResponse update(Long id, ArticleUpdateRequest request) { try { - Article article = articleRepository.findById(id); - Board board = boardRepository.findById(request.boardId()); - article.update(request.boardId(), request.title(), request.description()); - Article updated = articleRepository.update(article); - Member member = memberRepository.findById(updated.getAuthorId()); + Article article = articleRepository.findById(id) + .orElseThrow(IllegalArgumentException::new); + ; + Board board = boardRepository.findById(request.boardId()) + .orElseThrow(IllegalArgumentException::new); + ; + article.update(boardRepository.getReferenceById(request.boardId()), request.title(), request.description()); + Article updated = articleRepository.save(article); + Member member = memberRepository.findById(updated.getAuthorId()) + .orElseThrow(IllegalArgumentException::new); + ; return ArticleResponse.of(article, member, board); } catch (RuntimeException e) { throw new PutNotFoundException(e.getMessage()); diff --git a/src/main/java/com/example/demo/service/BoardService.java b/src/main/java/com/example/demo/service/BoardService.java index 4a04945..d136b54 100644 --- a/src/main/java/com/example/demo/service/BoardService.java +++ b/src/main/java/com/example/demo/service/BoardService.java @@ -6,7 +6,6 @@ import com.example.demo.AOPexception.Exception.GetNotFoundException; import com.example.demo.AOPexception.Exception.PostIllegalArgumemtException; import com.example.demo.repository.ArticleRepository; -import com.example.demo.repository.ArticleRepositoryJdbc; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -36,35 +35,35 @@ public List getBoards() { public BoardResponse getBoardById(Long id) { try { - Board board = boardRepository.findById(id); + Board board = boardRepository.findById(id).orElseThrow(IllegalArgumentException::new);; return BoardResponse.from(board); }catch (RuntimeException e) { throw new GetNotFoundException(e.getMessage()); } } - @Transactional public BoardResponse createBoard(BoardCreateRequest request) { if (request.name() == null ) { throw new PostIllegalArgumemtException("NULL field existed"); } Board board = new Board(request.name()); - Board saved = boardRepository.insert(board); + Board saved = boardRepository.save(board); return BoardResponse.from(saved); } + @Transactional public void deleteBoard(Long id) { - if(!articleRepository.findAllByBoardId(id).isEmpty()) + if(!articleRepository.findAllByBoard_Id(id).isEmpty()) throw new DeleteExistedExcepton("Articles exist in board!"); boardRepository.deleteById(id); } @Transactional public BoardResponse update(Long id, BoardUpdateRequest request) { - Board board = boardRepository.findById(id); + Board board = boardRepository.findById(id).orElseThrow(IllegalArgumentException::new);; board.update(request.name()); - Board updated = boardRepository.update(board); + Board updated = boardRepository.save(board); return BoardResponse.from(updated); } } diff --git a/src/main/java/com/example/demo/service/MemberService.java b/src/main/java/com/example/demo/service/MemberService.java index 75c0c79..7b8a35a 100644 --- a/src/main/java/com/example/demo/service/MemberService.java +++ b/src/main/java/com/example/demo/service/MemberService.java @@ -30,7 +30,7 @@ public MemberService(MemberRepository memberRepository, ArticleRepository articl public MemberResponse getById(Long id) { try { - Member member = memberRepository.findById(id); + Member member = memberRepository.findById(id).orElseThrow(IllegalArgumentException::new);; return MemberResponse.from(member); } catch (RuntimeException e) { throw new GetNotFoundException(e.getMessage()); @@ -49,7 +49,7 @@ public MemberResponse create(MemberCreateRequest request) { if (request.name() == null || request.email() == null || request.password() == null) { throw new PostIllegalArgumemtException("NULL field existed"); } - Member member = memberRepository.insert( + Member member = memberRepository.save( new Member(request.name(), request.email(), request.password()) ); return MemberResponse.from(member); @@ -57,19 +57,19 @@ public MemberResponse create(MemberCreateRequest request) { @Transactional public void delete(Long id) { - if (!articleRepository.findAllByMemberId(id).isEmpty()) + if (!articleRepository.findAllByAuthorId(id).isEmpty()) throw new DeleteExistedExcepton("one above articles existed written by this member"); memberRepository.deleteById(id); } @Transactional public MemberResponse update(Long id, MemberUpdateRequest request) { - Member member = memberRepository.findById(id); + Member member = memberRepository.findById(id).orElseThrow(IllegalArgumentException::new);; try { memberRepository.findByEmail(request.email()); } catch (RuntimeException e) { member.update(request.name(), request.email()); - memberRepository.update(member); + memberRepository.save(member); return MemberResponse.from(member); } throw new PutDuplicatedException("already used email"); From e96817ebaae89cc63a38323e6a93c345bc2b7273 Mon Sep 17 00:00:00 2001 From: FrozenInclude Date: Tue, 9 Jul 2024 12:13:18 +0900 Subject: [PATCH 6/8] implement login --- build.gradle | 6 +++ .../demo/AOPexception/ExceptHandler.java | 22 ++++++++ .../com/example/demo/config/AppConfig.java | 14 +++++ .../example/demo/config/SecurityConfig.java | 33 ++++++++++++ .../demo/controller/MemberController.java | 52 +++++++++++++++++-- .../dto/request/MemberCreateRequest.java | 14 +++-- .../dto/request/MemberLoginRequest.java | 8 +++ .../java/com/example/demo/domain/Article.java | 3 ++ .../java/com/example/demo/domain/Board.java | 2 + .../java/com/example/demo/domain/Member.java | 7 +++ .../demo/repository/MemberRepository.java | 3 +- .../example/demo/service/BoardService.java | 4 +- .../example/demo/service/MemberService.java | 46 +++++++++++++--- src/main/resources/application.yml | 2 +- 14 files changed, 197 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/example/demo/config/AppConfig.java create mode 100644 src/main/java/com/example/demo/config/SecurityConfig.java create mode 100644 src/main/java/com/example/demo/controller/dto/request/MemberLoginRequest.java diff --git a/build.gradle b/build.gradle index b158065..af5fc58 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,13 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0' + implementation 'org.springframework.boot:spring-boot-starter-security' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testCompileOnly 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/com/example/demo/AOPexception/ExceptHandler.java b/src/main/java/com/example/demo/AOPexception/ExceptHandler.java index 4fdf932..0e50deb 100644 --- a/src/main/java/com/example/demo/AOPexception/ExceptHandler.java +++ b/src/main/java/com/example/demo/AOPexception/ExceptHandler.java @@ -5,8 +5,14 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.HashMap; +import java.util.Map; + @RestControllerAdvice public class ExceptHandler { @ExceptionHandler @@ -34,6 +40,22 @@ public ResponseEntity handleException(DeleteExistedExcepton e) { return new ResponseEntity<>(new ErrorResponse(e.getMessage()),HttpStatus.BAD_REQUEST); } + @ExceptionHandler + public ResponseEntity handleException(RuntimeException e) { + return new ResponseEntity<>(new ErrorResponse(e.getMessage()),HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationExceptions(MethodArgumentNotValidException ex) { + Map errors = new HashMap<>(); + ex.getBindingResult().getAllErrors().forEach(error -> { + String fieldName = ((FieldError) error).getField(); + String errorMessage = error.getDefaultMessage(); + errors.put(fieldName, errorMessage); + }); + return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); + } + static class ErrorResponse { String message; diff --git a/src/main/java/com/example/demo/config/AppConfig.java b/src/main/java/com/example/demo/config/AppConfig.java new file mode 100644 index 0000000..3f88905 --- /dev/null +++ b/src/main/java/com/example/demo/config/AppConfig.java @@ -0,0 +1,14 @@ +package com.example.demo.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class AppConfig { + @Bean + public PasswordEncoder passwordEncoder() { + return PasswordEncoderFactories.createDelegatingPasswordEncoder(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/config/SecurityConfig.java b/src/main/java/com/example/demo/config/SecurityConfig.java new file mode 100644 index 0000000..683c785 --- /dev/null +++ b/src/main/java/com/example/demo/config/SecurityConfig.java @@ -0,0 +1,33 @@ +package com.example.demo.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception { + httpSecurity + .csrf(AbstractHttpConfigurer::disable) + .formLogin(AbstractHttpConfigurer::disable) + .authorizeHttpRequests(authorize -> authorize + .requestMatchers("/members/**").permitAll() + .anyRequest().authenticated()) + .exceptionHandling(configurer -> { + configurer.authenticationEntryPoint(((request, response, authException) -> { + + })); + configurer.accessDeniedHandler(((request, response, accessDeniedException) -> { + + })); + }); + return httpSecurity.build(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/controller/MemberController.java b/src/main/java/com/example/demo/controller/MemberController.java index ddb18ec..771a4a8 100644 --- a/src/main/java/com/example/demo/controller/MemberController.java +++ b/src/main/java/com/example/demo/controller/MemberController.java @@ -2,7 +2,13 @@ import java.util.List; +import com.example.demo.controller.dto.request.MemberLoginRequest; +import com.example.demo.domain.Member; +import jakarta.servlet.http.HttpSession; import org.springframework.http.ResponseEntity; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -31,9 +37,45 @@ public ResponseEntity> getMembers() { return ResponseEntity.ok(response); } + @PostMapping("/members/login") + public void login( + @RequestBody MemberLoginRequest request, + HttpSession session, + HttpServletResponse response + ) throws IOException { + Member existingUser = (Member) session.getAttribute("loginUser"); + if (existingUser != null) { + response.sendRedirect("/members/info"); + return; + } + Member user = memberService.login(request); + if (user == null) { + response.getWriter().write("로그인 아이디 또는 비밀번호가 틀렸습니다."); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + session.setAttribute("loginUser", user); + response.getWriter().write(String.format("loginId : %s login success!", user.getEmail())); + } + + @GetMapping("/members/info") + public String userInfo(HttpSession session) { + Member loginUser = (Member) session.getAttribute("loginUser"); + if (loginUser == null) { + return "로그인 상태가 아닙니다."; + } + return String.format("loginId : %s\nnickname : %s", loginUser.getEmail(), loginUser.getName()); + } + + @PostMapping("/members/logout") + public String logout(HttpSession session) { + session.invalidate(); + return "로그아웃 되었습니다."; + } + @GetMapping("/members/{id}") public ResponseEntity getMember( - @PathVariable Long id + @PathVariable Long id ) { MemberResponse response = memberService.getById(id); return ResponseEntity.ok(response); @@ -41,7 +83,7 @@ public ResponseEntity getMember( @PostMapping("/members") public ResponseEntity create( - @RequestBody MemberCreateRequest request + @Validated @RequestBody MemberCreateRequest request ) { MemberResponse response = memberService.create(request); return ResponseEntity.ok(response); @@ -49,8 +91,8 @@ public ResponseEntity create( @PutMapping("/members/{id}") public ResponseEntity updateMember( - @PathVariable Long id, - @RequestBody MemberUpdateRequest request + @PathVariable Long id, + @RequestBody MemberUpdateRequest request ) { MemberResponse response = memberService.update(id, request); return ResponseEntity.ok(response); @@ -58,7 +100,7 @@ public ResponseEntity updateMember( @DeleteMapping("/members/{id}") public ResponseEntity deleteMember( - @PathVariable Long id + @PathVariable Long id ) { memberService.delete(id); return ResponseEntity.noContent().build(); 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..8be1268 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,17 @@ package com.example.demo.controller.dto.request; + +import jakarta.validation.constraints.NotBlank; + public record MemberCreateRequest( - String name, - String email, - String password + @NotBlank(message = "이름을 입력해주세요.") + String name, + + @NotBlank(message = "이메일을 입력해주세요.") + String email, + + @NotBlank(message = "비밀번호를 입력해주세요.") + String password ) { } diff --git a/src/main/java/com/example/demo/controller/dto/request/MemberLoginRequest.java b/src/main/java/com/example/demo/controller/dto/request/MemberLoginRequest.java new file mode 100644 index 0000000..8b15039 --- /dev/null +++ b/src/main/java/com/example/demo/controller/dto/request/MemberLoginRequest.java @@ -0,0 +1,8 @@ +package com.example.demo.controller.dto.request; + +public record MemberLoginRequest( + String email, + String password +) +{ +} diff --git a/src/main/java/com/example/demo/domain/Article.java b/src/main/java/com/example/demo/domain/Article.java index c1a9714..5e42d5c 100644 --- a/src/main/java/com/example/demo/domain/Article.java +++ b/src/main/java/com/example/demo/domain/Article.java @@ -17,9 +17,12 @@ public class Article { private Board board; private String title; + private String content; + @Column(name = "created_date") private LocalDateTime createdAt; + @Column(name = "modified_date") private LocalDateTime modifiedAt; diff --git a/src/main/java/com/example/demo/domain/Board.java b/src/main/java/com/example/demo/domain/Board.java index ac46fa0..6f8be8f 100644 --- a/src/main/java/com/example/demo/domain/Board.java +++ b/src/main/java/com/example/demo/domain/Board.java @@ -10,7 +10,9 @@ public class Board { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + private String name; + @OneToMany(mappedBy = "board",cascade = CascadeType.ALL, orphanRemoval = true) private List
articles; diff --git a/src/main/java/com/example/demo/domain/Member.java b/src/main/java/com/example/demo/domain/Member.java index fa834a5..079c8a2 100644 --- a/src/main/java/com/example/demo/domain/Member.java +++ b/src/main/java/com/example/demo/domain/Member.java @@ -1,6 +1,7 @@ package com.example.demo.domain; import jakarta.persistence.*; +import org.springframework.security.crypto.password.PasswordEncoder; @Entity @Table(name = "member") @@ -8,8 +9,11 @@ public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + private String name; + private String email; + private String password; public Member(Long id, String name, String email, String password) { @@ -29,6 +33,9 @@ public Member() { } + public void encodePassword(PasswordEncoder passwordEncoder){ + this.password = passwordEncoder.encode(password); + } public void update(String name, String email) { this.name = name; this.email = email; diff --git a/src/main/java/com/example/demo/repository/MemberRepository.java b/src/main/java/com/example/demo/repository/MemberRepository.java index baad833..2dab276 100644 --- a/src/main/java/com/example/demo/repository/MemberRepository.java +++ b/src/main/java/com/example/demo/repository/MemberRepository.java @@ -1,10 +1,11 @@ package com.example.demo.repository; import java.util.List; +import java.util.Optional; import com.example.demo.domain.Member; import org.springframework.data.jpa.repository.JpaRepository; public interface MemberRepository extends JpaRepository { - Member findByEmail(String email); + Optional findByEmail(String email); } diff --git a/src/main/java/com/example/demo/service/BoardService.java b/src/main/java/com/example/demo/service/BoardService.java index d136b54..c6c0cda 100644 --- a/src/main/java/com/example/demo/service/BoardService.java +++ b/src/main/java/com/example/demo/service/BoardService.java @@ -54,8 +54,8 @@ public BoardResponse createBoard(BoardCreateRequest request) { @Transactional public void deleteBoard(Long id) { - if(!articleRepository.findAllByBoard_Id(id).isEmpty()) - throw new DeleteExistedExcepton("Articles exist in board!"); + //if(!articleRepository.findAllByBoard_Id(id).isEmpty()) + //throw new DeleteExistedExcepton("Articles 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 7b8a35a..6f3472c 100644 --- a/src/main/java/com/example/demo/service/MemberService.java +++ b/src/main/java/com/example/demo/service/MemberService.java @@ -1,12 +1,15 @@ package com.example.demo.service; import java.util.List; +import java.util.Optional; import com.example.demo.AOPexception.Exception.DeleteExistedExcepton; import com.example.demo.AOPexception.Exception.GetNotFoundException; -import com.example.demo.AOPexception.Exception.PostIllegalArgumemtException; import com.example.demo.AOPexception.Exception.PutDuplicatedException; +import com.example.demo.controller.dto.request.MemberLoginRequest; import com.example.demo.repository.ArticleRepository; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -22,15 +25,20 @@ public class MemberService { private final MemberRepository memberRepository; public final ArticleRepository articleRepository; + private final PasswordEncoder passwordEncoder; - public MemberService(MemberRepository memberRepository, ArticleRepository articleRepository) { + + public MemberService(MemberRepository memberRepository, ArticleRepository articleRepository, + PasswordEncoder passwordEncoder) { this.memberRepository = memberRepository; this.articleRepository = articleRepository; + this.passwordEncoder = passwordEncoder; } public MemberResponse getById(Long id) { try { - Member member = memberRepository.findById(id).orElseThrow(IllegalArgumentException::new);; + Member member = memberRepository.findById(id).orElseThrow(IllegalArgumentException::new); + ; return MemberResponse.from(member); } catch (RuntimeException e) { throw new GetNotFoundException(e.getMessage()); @@ -45,16 +53,39 @@ public List getAll() { } @Transactional - public MemberResponse create(MemberCreateRequest request) { - if (request.name() == null || request.email() == null || request.password() == null) { - throw new PostIllegalArgumemtException("NULL field existed"); + public MemberResponse create(MemberCreateRequest request) throws RuntimeException { + if (memberRepository.findByEmail(request.email()).isPresent()) { + throw new RuntimeException("이미 존재하는 이메일입니다."); } Member member = memberRepository.save( new Member(request.name(), request.email(), request.password()) ); + member.encodePassword(passwordEncoder); return MemberResponse.from(member); } + @Transactional + public Member login(MemberLoginRequest request) throws RuntimeException { + Optional optionalUser = memberRepository.findByEmail(request.email()); + if (optionalUser.isEmpty()) { + return null; + } + Member user = optionalUser.get(); + if (!passwordEncoder.matches(request.password(),user.getPassword())) { + return null; + } + return user; + } + + @Transactional + public Member getLoginUserByLoginId(String loginId) { + if (loginId == null) return null; + + Optional optionalUser = memberRepository.findByEmail(loginId); + return optionalUser.orElse(null); + + } + @Transactional public void delete(Long id) { if (!articleRepository.findAllByAuthorId(id).isEmpty()) @@ -64,7 +95,8 @@ public void delete(Long id) { @Transactional public MemberResponse update(Long id, MemberUpdateRequest request) { - Member member = memberRepository.findById(id).orElseThrow(IllegalArgumentException::new);; + Member member = memberRepository.findById(id).orElseThrow(IllegalArgumentException::new); + ; try { memberRepository.findByEmail(request.email()); } catch (RuntimeException e) { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 49c4ab0..105f0ba 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -5,4 +5,4 @@ spring: url: jdbc:mysql://localhost:3306/bcsd # 본인의 환경에 맞게 수정한다. driver-class-name: com.mysql.cj.jdbc.Driver username: root # 본인의 환경에 맞게 수정한다. - password: gkrdlsdlelql!! # 본인의 환경에 맞게 수정한다. + password: gkrdlsdlelql!! # 본인의 환경에 맞게 수정한다. \ No newline at end of file From 3996d4c81700c00182a64141b96111c19435bfd8 Mon Sep 17 00:00:00 2001 From: FrozenInclude Date: Tue, 9 Jul 2024 12:44:09 +0900 Subject: [PATCH 7/8] simpify login --- .../demo/controller/MemberController.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/example/demo/controller/MemberController.java b/src/main/java/com/example/demo/controller/MemberController.java index 771a4a8..68d04fa 100644 --- a/src/main/java/com/example/demo/controller/MemberController.java +++ b/src/main/java/com/example/demo/controller/MemberController.java @@ -5,9 +5,13 @@ import com.example.demo.controller.dto.request.MemberLoginRequest; import com.example.demo.domain.Member; import jakarta.servlet.http.HttpSession; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; + import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -38,24 +42,25 @@ public ResponseEntity> getMembers() { } @PostMapping("/members/login") - public void login( + public ResponseEntity login( @RequestBody MemberLoginRequest request, - HttpSession session, - HttpServletResponse response - ) throws IOException { + HttpSession session + ) { Member existingUser = (Member) session.getAttribute("loginUser"); if (existingUser != null) { - response.sendRedirect("/members/info"); - return; + return ResponseEntity.status(HttpStatus.FOUND) + .header(HttpHeaders.LOCATION, "/members/info") + .build(); } + Member user = memberService.login(request); if (user == null) { - response.getWriter().write("로그인 아이디 또는 비밀번호가 틀렸습니다."); - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - return; + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body("로그인 아이디 또는 비밀번호가 틀렸습니다."); } + session.setAttribute("loginUser", user); - response.getWriter().write(String.format("loginId : %s login success!", user.getEmail())); + return ResponseEntity.ok(String.format("loginId : %s login success!", user.getEmail())); } @GetMapping("/members/info") From fb4f6669b6fde19bb0b8e468abb3ff18c0597620 Mon Sep 17 00:00:00 2001 From: Kim Hak In Date: Tue, 23 Jul 2024 01:40:33 +0900 Subject: [PATCH 8/8] Update README.md --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 0a0d3b4..6c9f94a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,5 @@ ## API Documentation -### Base URL - -``` -http://localhost:8080 -``` - ### Endpoints | Method | Endpoint | Description | Parameters | Headers | Body |