From 1c2bb44ca9eb305761fdf60fe6eb9cc15749fdfc Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Fri, 9 May 2025 22:09:20 +0900 Subject: [PATCH 01/22] =?UTF-8?q?=EC=9E=90=EA=B8=B0=EC=86=8C=EA=B0=9C=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/bcsd/HelloController.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/example/bcsd/HelloController.java b/src/main/java/com/example/bcsd/HelloController.java index 9559e2f1..c1b705d5 100644 --- a/src/main/java/com/example/bcsd/HelloController.java +++ b/src/main/java/com/example/bcsd/HelloController.java @@ -2,19 +2,26 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import java.util.HashMap; +import java.util.Map; + @Controller public class HelloController { @ResponseBody - @GetMapping("/hello") - public String hello() { - return "Hello World!!!!!"; + @GetMapping("/introduce") + public String introduce(@RequestParam(name = "name", required = false, defaultValue = "홍길동") String name) { + return "안녕하세요 제 이름은 " + name + "입니다!"; } - - @GetMapping("/hello2") - public String hello2() { - return "hello"; + @ResponseBody + @GetMapping("/json") + public Map json() { + Map map = new HashMap<>(); + map.put("age", 26); + map.put("name", "허준기"); + return map; } -} +} \ No newline at end of file From d17c235936b02ee11fac1530298e6fc3a816255d Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Fri, 9 May 2025 22:10:30 +0900 Subject: [PATCH 02/22] =?UTF-8?q?=EC=9D=91=EB=8B=B5=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20CRUD=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/bcsd/articleController.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/com/example/bcsd/articleController.java diff --git a/src/main/java/com/example/bcsd/articleController.java b/src/main/java/com/example/bcsd/articleController.java new file mode 100644 index 00000000..fff26c79 --- /dev/null +++ b/src/main/java/com/example/bcsd/articleController.java @@ -0,0 +1,43 @@ +package com.example.bcsd; + +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/article") +public class articleController { + private final Map articles = new HashMap<>(); + private Integer articleId = 1; + + @PostMapping + public String postArticle(@RequestBody String articleName) { + articles.put(articleId, articleName); + return "Item created " + articleId; + } + + @GetMapping("/{id}") + public String getArticle(@PathVariable("id") int id) { + return articles.get(id); + } + + @PutMapping("/{id}") + public String putArticle(@PathVariable int id, @RequestBody String articleName) { + if(!articles.containsKey(id)) { + return "Item not found"; + } + articles.put(id, articleName); + return "Item updated " + articleName; + } + + @DeleteMapping("/{id}") + public String deleteArticle(@PathVariable int id) { + if(!articles.containsKey(id)) { + return "Item not found"; + } + articles.remove(id); + return "Item deleted " + articleId; + } + +} From 6a0e82e983b2c8a8944ff36ceb7ed0f3c74ffaf8 Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Sun, 11 May 2025 10:06:34 +0900 Subject: [PATCH 03/22] =?UTF-8?q?5=EC=A3=BC=EC=B0=A8=20=EA=B3=BC=EC=A0=9C?= =?UTF-8?q?=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/bcsd/ArticleController.java | 81 +++++++++++++++++++ .../com/example/bcsd/articleController.java | 43 ---------- 2 files changed, 81 insertions(+), 43 deletions(-) create mode 100644 src/main/java/com/example/bcsd/ArticleController.java delete mode 100644 src/main/java/com/example/bcsd/articleController.java diff --git a/src/main/java/com/example/bcsd/ArticleController.java b/src/main/java/com/example/bcsd/ArticleController.java new file mode 100644 index 00000000..07783b46 --- /dev/null +++ b/src/main/java/com/example/bcsd/ArticleController.java @@ -0,0 +1,81 @@ +package com.example.bcsd; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/article") +public class ArticleController { + private final Map articles = new HashMap<>(); + private Integer articleId = 1; + + @PostMapping + public ResponseEntity> postArticle(@RequestBody Map requestBody) { + String description = requestBody.get("description"); + + if (description == null) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Description is missing"); + return ResponseEntity.badRequest().body(errorResponse); + } + + Integer currentIdToUse = articleId; + articles.put(currentIdToUse, description); + + Map response = new HashMap<>(); + response.put("id", currentIdToUse); + response.put("description", description); + + articleId++; + + return ResponseEntity.status(HttpStatus.CREATED).body(response); + } + + @GetMapping("/{id}") + public ResponseEntity> getArticle(@PathVariable("id") Integer id) { + String description = articles.get(id); + + if (description != null) { + Map response = new HashMap<>(); + response.put("id", id); + response.put("description", description); + return ResponseEntity.ok(response); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); + } + } + + @PutMapping("/{id}") + public ResponseEntity> putArticle(@PathVariable Integer id, @RequestBody Map requestBody) { + String newDescription = requestBody.get("description"); + + if (newDescription == null) { + Map errorResponse = new HashMap<>(); + errorResponse.put("error", "Description is missing for update"); + return ResponseEntity.badRequest().body(errorResponse); + } + + if (!articles.containsKey(id)) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); + } + + articles.put(id, newDescription); + + Map response = new HashMap<>(); + response.put("id", id); + response.put("description", newDescription); + return ResponseEntity.ok(response); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteArticle(@PathVariable Integer id) { + if (articles.containsKey(id)) { + articles.remove(id); + } + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/articleController.java b/src/main/java/com/example/bcsd/articleController.java deleted file mode 100644 index fff26c79..00000000 --- a/src/main/java/com/example/bcsd/articleController.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.example.bcsd; - -import org.springframework.web.bind.annotation.*; - -import java.util.HashMap; -import java.util.Map; - -@RestController -@RequestMapping("/article") -public class articleController { - private final Map articles = new HashMap<>(); - private Integer articleId = 1; - - @PostMapping - public String postArticle(@RequestBody String articleName) { - articles.put(articleId, articleName); - return "Item created " + articleId; - } - - @GetMapping("/{id}") - public String getArticle(@PathVariable("id") int id) { - return articles.get(id); - } - - @PutMapping("/{id}") - public String putArticle(@PathVariable int id, @RequestBody String articleName) { - if(!articles.containsKey(id)) { - return "Item not found"; - } - articles.put(id, articleName); - return "Item updated " + articleName; - } - - @DeleteMapping("/{id}") - public String deleteArticle(@PathVariable int id) { - if(!articles.containsKey(id)) { - return "Item not found"; - } - articles.remove(id); - return "Item deleted " + articleId; - } - -} From 3a28a036a5a145b00b7ab4bcbb9df2860e0907eb Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 12 May 2025 13:34:34 +0900 Subject: [PATCH 04/22] =?UTF-8?q?=EB=AA=A8=EB=93=A0=20article=EC=9D=84=20?= =?UTF-8?q?=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8A=94=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EC=99=80=20json=EC=9D=84=20=EB=B3=B4=EC=97=AC=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20=EB=AA=A8=EB=8D=B8=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/bcsd/ArticleController.java | 59 ++++++++---- .../java/com/example/bcsd/models/Article.java | 93 +++++++++++++++++++ .../java/com/example/bcsd/models/Board.java | 27 ++++++ .../java/com/example/bcsd/models/Member.java | 48 ++++++++++ src/main/resources/templates/articles.html | 10 ++ 5 files changed, 221 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/example/bcsd/models/Article.java create mode 100644 src/main/java/com/example/bcsd/models/Board.java create mode 100644 src/main/java/com/example/bcsd/models/Member.java create mode 100644 src/main/resources/templates/articles.html diff --git a/src/main/java/com/example/bcsd/ArticleController.java b/src/main/java/com/example/bcsd/ArticleController.java index 07783b46..3fd08ced 100644 --- a/src/main/java/com/example/bcsd/ArticleController.java +++ b/src/main/java/com/example/bcsd/ArticleController.java @@ -2,43 +2,44 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; -@RestController -@RequestMapping("/article") +@Controller public class ArticleController { + private final Map articles = new HashMap<>(); private Integer articleId = 1; - @PostMapping + @PostMapping("/article") + @ResponseBody public ResponseEntity> postArticle(@RequestBody Map requestBody) { String description = requestBody.get("description"); - if (description == null) { Map errorResponse = new HashMap<>(); errorResponse.put("error", "Description is missing"); return ResponseEntity.badRequest().body(errorResponse); } - Integer currentIdToUse = articleId; articles.put(currentIdToUse, description); - Map response = new HashMap<>(); response.put("id", currentIdToUse); response.put("description", description); - articleId++; - return ResponseEntity.status(HttpStatus.CREATED).body(response); } - @GetMapping("/{id}") + @GetMapping("/article/{id}") + @ResponseBody public ResponseEntity> getArticle(@PathVariable("id") Integer id) { String description = articles.get(id); - if (description != null) { Map response = new HashMap<>(); response.put("id", id); @@ -49,33 +50,59 @@ public ResponseEntity> getArticle(@PathVariable("id") Intege } } - @PutMapping("/{id}") + @PutMapping("/article/{id}") + @ResponseBody public ResponseEntity> putArticle(@PathVariable Integer id, @RequestBody Map requestBody) { String newDescription = requestBody.get("description"); - if (newDescription == null) { Map errorResponse = new HashMap<>(); errorResponse.put("error", "Description is missing for update"); return ResponseEntity.badRequest().body(errorResponse); } - if (!articles.containsKey(id)) { return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); } - articles.put(id, newDescription); - Map response = new HashMap<>(); response.put("id", id); response.put("description", newDescription); return ResponseEntity.ok(response); } - @DeleteMapping("/{id}") + @DeleteMapping("/article/{id}") + @ResponseBody public ResponseEntity deleteArticle(@PathVariable Integer id) { if (articles.containsKey(id)) { articles.remove(id); } return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); } + + @GetMapping("/articles") + @ResponseBody + public ResponseEntity>> getAllArticlesApi() { + List> allArticlesList = new ArrayList<>(); + for (Map.Entry entry : articles.entrySet()) { + Map articleMap = new HashMap<>(); + articleMap.put("id", entry.getKey()); + articleMap.put("description", entry.getValue()); + allArticlesList.add(articleMap); + } + return ResponseEntity.ok(allArticlesList); + } + + @GetMapping("/posts") + public String getAllArticlesView(Model model) { + List> articlesForView = articles.entrySet().stream() + .map(entry -> { + Map article = new HashMap<>(); + article.put("id", entry.getKey()); + article.put("description", entry.getValue()); + return article; + }) + .collect(Collectors.toList()); + + model.addAttribute("articles", articlesForView); + return "articles"; + } } \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Article.java b/src/main/java/com/example/bcsd/models/Article.java new file mode 100644 index 00000000..17b715db --- /dev/null +++ b/src/main/java/com/example/bcsd/models/Article.java @@ -0,0 +1,93 @@ +package com.example.bcsd.models; + +import java.time.LocalDateTime; + +public class Article { + private Integer id; + private Integer authorId; + private Integer boardId; + private String title; + private String content; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; + + public Article() { + this.createdAt = LocalDateTime.now(); + this.updatedAt = LocalDateTime.now(); + } + + public Article(Integer authorId, Integer boardId, String title, String content) { + this.authorId = authorId; + this.boardId = boardId; + this.title = title; + this.content = content; + this.createdAt = LocalDateTime.now(); + this.updatedAt = LocalDateTime.now(); + } + + public Article(Integer id, Integer authorId, Integer boardId, String title, String content, LocalDateTime createdAt, LocalDateTime updatedAt) { + this.id = id; + this.authorId = authorId; + this.boardId = boardId; + this.title = title; + this.content = content; + this.createdAt = createdAt; + this.updatedAt = updatedAt; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getAuthorId() { + return authorId; + } + + public void setAuthorId(Integer authorId) { + this.authorId = authorId; + } + + public Integer getBoardId() { + return boardId; + } + + public void setBoardId(Integer boardId) { + this.boardId = boardId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Board.java b/src/main/java/com/example/bcsd/models/Board.java new file mode 100644 index 00000000..5d72cc40 --- /dev/null +++ b/src/main/java/com/example/bcsd/models/Board.java @@ -0,0 +1,27 @@ +package com.example.bcsd.models; + +public class Board { + private Integer id; + private String name; + + public Board(Integer id, String name) { + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Member.java b/src/main/java/com/example/bcsd/models/Member.java new file mode 100644 index 00000000..2968a837 --- /dev/null +++ b/src/main/java/com/example/bcsd/models/Member.java @@ -0,0 +1,48 @@ +package com.example.bcsd.models; + +public class Member { + private Integer id; + private String name; + private String email; + private String password; + + public Member(Integer id, String name, String email, String password) { + this.id = id; + this.name = name; + this.email = email; + this.password = password; + } + + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} \ No newline at end of file diff --git a/src/main/resources/templates/articles.html b/src/main/resources/templates/articles.html new file mode 100644 index 00000000..78361404 --- /dev/null +++ b/src/main/resources/templates/articles.html @@ -0,0 +1,10 @@ + + + + + Articles + + +

article을 보여주기 위한 페이지

+ + \ No newline at end of file From c3de8a6372155eb0e349fdff29f62c3763c537c9 Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 12 May 2025 14:53:57 +0900 Subject: [PATCH 05/22] =?UTF-8?q?view=EC=9E=91=EC=84=B1=20=EB=B0=8F=20cont?= =?UTF-8?q?roller=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/bcsd/ArticleController.java | 125 ++++++++---------- src/main/resources/templates/articles.html | 18 ++- 2 files changed, 69 insertions(+), 74 deletions(-) diff --git a/src/main/java/com/example/bcsd/ArticleController.java b/src/main/java/com/example/bcsd/ArticleController.java index 3fd08ced..a5d95c81 100644 --- a/src/main/java/com/example/bcsd/ArticleController.java +++ b/src/main/java/com/example/bcsd/ArticleController.java @@ -1,108 +1,93 @@ package com.example.bcsd; +import com.example.bcsd.models.Article; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; +import java.time.LocalDateTime; +import java.util.*; @Controller public class ArticleController { - private final Map articles = new HashMap<>(); + private final Map articles = new HashMap<>(); private Integer articleId = 1; @PostMapping("/article") @ResponseBody - public ResponseEntity> postArticle(@RequestBody Map requestBody) { - String description = requestBody.get("description"); - if (description == null) { - Map errorResponse = new HashMap<>(); - errorResponse.put("error", "Description is missing"); - return ResponseEntity.badRequest().body(errorResponse); + public ResponseEntity createArticle(@RequestBody Map body) { + try { + Integer authorId = Integer.parseInt(body.get("authorId")); + Integer boardId = Integer.parseInt(body.get("boardId")); + String title = body.get("title"); + String content = body.get("content"); + + if (title == null || content == null) { + return ResponseEntity.badRequest().body("Title or content is missing"); + } + + Article article = new Article(articleId, authorId, boardId, title, content, LocalDateTime.now(), LocalDateTime.now()); + articles.put(articleId, article); + articleId++; + + return ResponseEntity.status(HttpStatus.CREATED).body(article); + } catch (Exception e) { + return ResponseEntity.badRequest().body("Invalid input"); } - Integer currentIdToUse = articleId; - articles.put(currentIdToUse, description); - Map response = new HashMap<>(); - response.put("id", currentIdToUse); - response.put("description", description); - articleId++; - return ResponseEntity.status(HttpStatus.CREATED).body(response); + } + + @GetMapping("/articles") + @ResponseBody + public ResponseEntity> getAllArticles() { + return ResponseEntity.ok(new ArrayList<>(articles.values())); } @GetMapping("/article/{id}") @ResponseBody - public ResponseEntity> getArticle(@PathVariable("id") Integer id) { - String description = articles.get(id); - if (description != null) { - Map response = new HashMap<>(); - response.put("id", id); - response.put("description", description); - return ResponseEntity.ok(response); - } else { - return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); + public ResponseEntity getArticle(@PathVariable Integer id) { + Article article = articles.get(id); + if (article == null) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); } + return ResponseEntity.ok(article); } @PutMapping("/article/{id}") @ResponseBody - public ResponseEntity> putArticle(@PathVariable Integer id, @RequestBody Map requestBody) { - String newDescription = requestBody.get("description"); - if (newDescription == null) { - Map errorResponse = new HashMap<>(); - errorResponse.put("error", "Description is missing for update"); - return ResponseEntity.badRequest().body(errorResponse); + public ResponseEntity updateArticle(@PathVariable Integer id, @RequestBody Map body) { + Article article = articles.get(id); + if (article == null) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); } - if (!articles.containsKey(id)) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); + + if (body.containsKey("title")) { + article.setTitle(body.get("title")); } - articles.put(id, newDescription); - Map response = new HashMap<>(); - response.put("id", id); - response.put("description", newDescription); - return ResponseEntity.ok(response); + if (body.containsKey("content")) { + article.setContent(body.get("content")); + } + + article.setUpdatedAt(LocalDateTime.now()); + + return ResponseEntity.ok(article); } @DeleteMapping("/article/{id}") @ResponseBody - public ResponseEntity deleteArticle(@PathVariable Integer id) { - if (articles.containsKey(id)) { - articles.remove(id); + public ResponseEntity deleteArticle(@PathVariable Integer id) { + if (!articles.containsKey(id)) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); } + articles.remove(id); return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); } - @GetMapping("/articles") - @ResponseBody - public ResponseEntity>> getAllArticlesApi() { - List> allArticlesList = new ArrayList<>(); - for (Map.Entry entry : articles.entrySet()) { - Map articleMap = new HashMap<>(); - articleMap.put("id", entry.getKey()); - articleMap.put("description", entry.getValue()); - allArticlesList.add(articleMap); - } - return ResponseEntity.ok(allArticlesList); - } - @GetMapping("/posts") - public String getAllArticlesView(Model model) { - List> articlesForView = articles.entrySet().stream() - .map(entry -> { - Map article = new HashMap<>(); - article.put("id", entry.getKey()); - article.put("description", entry.getValue()); - return article; - }) - .collect(Collectors.toList()); - - model.addAttribute("articles", articlesForView); - return "articles"; + public String showAllArticlesView(Model model) { + model.addAttribute("articles", new ArrayList<>(articles.values())); + return "articles"; } -} \ No newline at end of file +} diff --git a/src/main/resources/templates/articles.html b/src/main/resources/templates/articles.html index 78361404..dc4da976 100644 --- a/src/main/resources/templates/articles.html +++ b/src/main/resources/templates/articles.html @@ -1,10 +1,20 @@ - + - Articles + 게시글 목록 -

article을 보여주기 위한 페이지

+

게시글 목록

+ +
+

제목

+

내용

+

작성자

+

게시판

+

작성일

+

수정일

+
+
- \ No newline at end of file + From a36bda397c4603c0d7ccf7c22fd1a31b9705181f Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 19 May 2025 23:23:47 +0900 Subject: [PATCH 06/22] =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20=EB=B0=8F=20html?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=88=98=EC=A0=95,=20controller=EB=8A=94?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 6 ++ .../com/example/bcsd/ArticleController.java | 51 ++++++++--- .../java/com/example/bcsd/models/Article.java | 88 ++++++------------- .../java/com/example/bcsd/models/Board.java | 24 +++-- .../java/com/example/bcsd/models/Member.java | 23 ++--- src/main/resources/templates/articles.html | 20 ----- src/main/resources/templates/boards.html | 14 +++ src/main/resources/templates/posts.html | 16 ++++ 8 files changed, 120 insertions(+), 122 deletions(-) delete mode 100644 src/main/resources/templates/articles.html create mode 100644 src/main/resources/templates/boards.html create mode 100644 src/main/resources/templates/posts.html diff --git a/build.gradle b/build.gradle index db3ebcf1..b4041e18 100644 --- a/build.gradle +++ b/build.gradle @@ -18,10 +18,16 @@ repositories { } dependencies { + // Spring Boot 핵심 implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-jdbc' + + runtimeOnly 'mysql:mysql-connector-java:8.0.42' + testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + } tasks.named('test') { diff --git a/src/main/java/com/example/bcsd/ArticleController.java b/src/main/java/com/example/bcsd/ArticleController.java index a5d95c81..0b7052d0 100644 --- a/src/main/java/com/example/bcsd/ArticleController.java +++ b/src/main/java/com/example/bcsd/ArticleController.java @@ -16,12 +16,45 @@ public class ArticleController { private final Map articles = new HashMap<>(); private Integer articleId = 1; - @PostMapping("/article") + @GetMapping("/posts") + public String showArticlesView( @RequestParam(name = "boardId", required = false) Integer boardId, Model model) { + + List
allArticles = new ArrayList<>(articles.values()); + allArticles.sort(Comparator.comparing(Article::getId)); + Map boardModelData = new HashMap<>(); + + if (boardId != null) { + boardModelData.put("id", boardId); + boardModelData.put("name", "게시판 " + boardId); + model.addAttribute("boardId", boardId); + } else { + boardModelData.put("name", "전체"); + } + + model.addAttribute("board", boardModelData); + model.addAttribute("articles", allArticles); + + return "boards"; + } + + @GetMapping("/articles") + @ResponseBody + public ResponseEntity> getArticlesByBoardId( + @RequestParam(name = "boardId", required = false) Integer boardId) { // boardId 파라미터는 받지만, 필터링에 사용되지 않음 + + List
allArticles = new ArrayList<>(articles.values()); + + allArticles.sort(Comparator.comparing(Article::getId)); + + return ResponseEntity.ok(allArticles); + } + + @PostMapping("/articles") @ResponseBody public ResponseEntity createArticle(@RequestBody Map body) { try { - Integer authorId = Integer.parseInt(body.get("authorId")); - Integer boardId = Integer.parseInt(body.get("boardId")); + Integer authorId = Integer.parseInt(body.get("author_id")); + Integer boardId = Integer.parseInt(body.get("board_id")); String title = body.get("title"); String content = body.get("content"); @@ -45,7 +78,7 @@ public ResponseEntity> getAllArticles() { return ResponseEntity.ok(new ArrayList<>(articles.values())); } - @GetMapping("/article/{id}") + @GetMapping("/articles/{id}") @ResponseBody public ResponseEntity getArticle(@PathVariable Integer id) { Article article = articles.get(id); @@ -55,7 +88,7 @@ public ResponseEntity getArticle(@PathVariable Integer id) { return ResponseEntity.ok(article); } - @PutMapping("/article/{id}") + @PutMapping("/articles/{id}") @ResponseBody public ResponseEntity updateArticle(@PathVariable Integer id, @RequestBody Map body) { Article article = articles.get(id); @@ -75,7 +108,7 @@ public ResponseEntity updateArticle(@PathVariable Integer id, @RequestBody Ma return ResponseEntity.ok(article); } - @DeleteMapping("/article/{id}") + @DeleteMapping("/articles/{id}") @ResponseBody public ResponseEntity deleteArticle(@PathVariable Integer id) { if (!articles.containsKey(id)) { @@ -84,10 +117,4 @@ public ResponseEntity deleteArticle(@PathVariable Integer id) { articles.remove(id); return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); } - - @GetMapping("/posts") - public String showAllArticlesView(Model model) { - model.addAttribute("articles", new ArrayList<>(articles.values())); - return "articles"; - } } diff --git a/src/main/java/com/example/bcsd/models/Article.java b/src/main/java/com/example/bcsd/models/Article.java index 17b715db..af77c545 100644 --- a/src/main/java/com/example/bcsd/models/Article.java +++ b/src/main/java/com/example/bcsd/models/Article.java @@ -1,93 +1,57 @@ package com.example.bcsd.models; -import java.time.LocalDateTime; - public class Article { - private Integer id; - private Integer authorId; - private Integer boardId; - private String title; - private String content; - private LocalDateTime createdAt; - private LocalDateTime updatedAt; - - public Article() { - this.createdAt = LocalDateTime.now(); - this.updatedAt = LocalDateTime.now(); - } - - public Article(Integer authorId, Integer boardId, String title, String content) { - this.authorId = authorId; - this.boardId = boardId; - this.title = title; - this.content = content; - this.createdAt = LocalDateTime.now(); - this.updatedAt = LocalDateTime.now(); - } - - public Article(Integer id, Integer authorId, Integer boardId, String title, String content, LocalDateTime createdAt, LocalDateTime updatedAt) { + private final Long id; + private final String title; + private final Long authorId; + private final Long boardId; + private final String createdDate; + private final String content; + private final String modifiedDate; + + public Article(Long id, String title, Long authorId, Long boardId, String createdAt, String content, String modifiedDate) { this.id = id; + this.title = title; this.authorId = authorId; this.boardId = boardId; - this.title = title; + this.createdDate = createdAt; this.content = content; - this.createdAt = createdAt; - this.updatedAt = updatedAt; + this.modifiedDate = modifiedDate; } - public Integer getId() { + public Long getId() { return id; } - public void setId(Integer id) { - this.id = id; + public String getTitle() { + return title; } - public Integer getAuthorId() { - return authorId; + public Article changeArticle(String title, String content, String modifiedDate) { + return new Article(id, title, authorId, boardId, createdDate, content, modifiedDate); } - public void setAuthorId(Integer authorId) { - this.authorId = authorId; + public Long getAuthorId() { + return authorId; } - public Integer getBoardId() { + public Long getBoardId() { return boardId; } - public void setBoardId(Integer boardId) { - this.boardId = boardId; + public String getCreatedDate() { + return createdDate; } - public String getTitle() { - return title; + public String getModifiedDate() { + return modifiedDate; } - public void setTitle(String title) { - this.title = title; + public Article updateModificationDate(String date) { + return new Article(id, title, authorId, boardId, createdDate, content, date); } public String getContent() { return content; } - - public void setContent(String content) { - this.content = content; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } } \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Board.java b/src/main/java/com/example/bcsd/models/Board.java index 5d72cc40..83d2c87f 100644 --- a/src/main/java/com/example/bcsd/models/Board.java +++ b/src/main/java/com/example/bcsd/models/Board.java @@ -1,27 +1,23 @@ package com.example.bcsd.models; public class Board { - private Integer id; - private String name; + private final Long id; + private final String title; - public Board(Integer id, String name) { + public Board(Long id, String title) { this.id = id; - this.name = name; + this.title = title; } - public Integer getId() { - return id; + public String getTitle() { + return title; } - public void setId(Integer id) { - this.id = id; + public Board changeTitle(String title) { + return new Board(id, title); } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; + public Long getId() { + return id; } } \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Member.java b/src/main/java/com/example/bcsd/models/Member.java index 2968a837..33bc893f 100644 --- a/src/main/java/com/example/bcsd/models/Member.java +++ b/src/main/java/com/example/bcsd/models/Member.java @@ -1,48 +1,43 @@ package com.example.bcsd.models; public class Member { - private Integer id; + private Long id; private String name; private String email; private String password; - public Member(Integer id, String name, String email, String password) { + public Member(Long id, String name, String email, String password) { this.id = id; this.name = name; this.email = email; this.password = password; } - - public Integer getId() { + public Long getId() { return id; } - public void setId(Integer id) { - this.id = id; - } - public String getName() { return name; } - public void setName(String name) { - this.name = name; + public Member changeName(String name) { + return new Member(id, name, email, password); } public String getEmail() { return email; } - public void setEmail(String email) { - this.email = email; + public Member changeEmail(String email) { + return new Member(id, name, email, password); } public String getPassword() { return password; } - public void setPassword(String password) { - this.password = password; + public Member changePassword(String password) { + return new Member(id, name, email, password); } } \ No newline at end of file diff --git a/src/main/resources/templates/articles.html b/src/main/resources/templates/articles.html deleted file mode 100644 index dc4da976..00000000 --- a/src/main/resources/templates/articles.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - 게시글 목록 - - -

게시글 목록

- -
-

제목

-

내용

-

작성자

-

게시판

-

작성일

-

수정일

-
-
- - diff --git a/src/main/resources/templates/boards.html b/src/main/resources/templates/boards.html new file mode 100644 index 00000000..f4179c88 --- /dev/null +++ b/src/main/resources/templates/boards.html @@ -0,0 +1,14 @@ + + + + Board Posts + + +

Board:

+ + + \ No newline at end of file diff --git a/src/main/resources/templates/posts.html b/src/main/resources/templates/posts.html new file mode 100644 index 00000000..44492e66 --- /dev/null +++ b/src/main/resources/templates/posts.html @@ -0,0 +1,16 @@ + + + + + + 게시판 + + +

+
+

+ +

+
+ + \ No newline at end of file From 662939fdf7c126a62b2dc5508f539741cccf91ea Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Tue, 20 May 2025 14:43:23 +0900 Subject: [PATCH 07/22] =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20=EC=A0=95=EC=9D=98?= =?UTF-8?q?=20=EB=B0=8F=20API=201=EB=B2=88=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 +- .../com/example/bcsd/ArticleController.java | 120 ------------------ .../bcsd/controllers/ArticleController.java | 0 .../bcsd/controllers/BoardController.java | 17 +++ .../java/com/example/bcsd/daos/boardDao.java | 26 ++++ .../java/com/example/bcsd/dtos/boardDto.java | 30 +++++ .../java/com/example/bcsd/models/Article.java | 88 +++++++++---- .../java/com/example/bcsd/models/Board.java | 23 ++-- .../java/com/example/bcsd/models/Member.java | 19 ++- .../example/bcsd/services/boardService.java | 23 ++++ 10 files changed, 187 insertions(+), 164 deletions(-) delete mode 100644 src/main/java/com/example/bcsd/ArticleController.java create mode 100644 src/main/java/com/example/bcsd/controllers/ArticleController.java create mode 100644 src/main/java/com/example/bcsd/controllers/BoardController.java create mode 100644 src/main/java/com/example/bcsd/daos/boardDao.java create mode 100644 src/main/java/com/example/bcsd/dtos/boardDto.java create mode 100644 src/main/java/com/example/bcsd/services/boardService.java diff --git a/build.gradle b/build.gradle index b4041e18..72214f03 100644 --- a/build.gradle +++ b/build.gradle @@ -23,10 +23,9 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-jdbc' - runtimeOnly 'mysql:mysql-connector-java:8.0.42' - + implementation 'org.springframework.boot:spring-boot-starter' + runtimeOnly 'com.mysql:mysql-connector-j' testImplementation 'org.springframework.boot:spring-boot-starter-test' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } diff --git a/src/main/java/com/example/bcsd/ArticleController.java b/src/main/java/com/example/bcsd/ArticleController.java deleted file mode 100644 index 0b7052d0..00000000 --- a/src/main/java/com/example/bcsd/ArticleController.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.example.bcsd; - -import com.example.bcsd.models.Article; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; - -import java.time.LocalDateTime; -import java.util.*; - -@Controller -public class ArticleController { - - private final Map articles = new HashMap<>(); - private Integer articleId = 1; - - @GetMapping("/posts") - public String showArticlesView( @RequestParam(name = "boardId", required = false) Integer boardId, Model model) { - - List
allArticles = new ArrayList<>(articles.values()); - allArticles.sort(Comparator.comparing(Article::getId)); - Map boardModelData = new HashMap<>(); - - if (boardId != null) { - boardModelData.put("id", boardId); - boardModelData.put("name", "게시판 " + boardId); - model.addAttribute("boardId", boardId); - } else { - boardModelData.put("name", "전체"); - } - - model.addAttribute("board", boardModelData); - model.addAttribute("articles", allArticles); - - return "boards"; - } - - @GetMapping("/articles") - @ResponseBody - public ResponseEntity> getArticlesByBoardId( - @RequestParam(name = "boardId", required = false) Integer boardId) { // boardId 파라미터는 받지만, 필터링에 사용되지 않음 - - List
allArticles = new ArrayList<>(articles.values()); - - allArticles.sort(Comparator.comparing(Article::getId)); - - return ResponseEntity.ok(allArticles); - } - - @PostMapping("/articles") - @ResponseBody - public ResponseEntity createArticle(@RequestBody Map body) { - try { - Integer authorId = Integer.parseInt(body.get("author_id")); - Integer boardId = Integer.parseInt(body.get("board_id")); - String title = body.get("title"); - String content = body.get("content"); - - if (title == null || content == null) { - return ResponseEntity.badRequest().body("Title or content is missing"); - } - - Article article = new Article(articleId, authorId, boardId, title, content, LocalDateTime.now(), LocalDateTime.now()); - articles.put(articleId, article); - articleId++; - - return ResponseEntity.status(HttpStatus.CREATED).body(article); - } catch (Exception e) { - return ResponseEntity.badRequest().body("Invalid input"); - } - } - - @GetMapping("/articles") - @ResponseBody - public ResponseEntity> getAllArticles() { - return ResponseEntity.ok(new ArrayList<>(articles.values())); - } - - @GetMapping("/articles/{id}") - @ResponseBody - public ResponseEntity getArticle(@PathVariable Integer id) { - Article article = articles.get(id); - if (article == null) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); - } - return ResponseEntity.ok(article); - } - - @PutMapping("/articles/{id}") - @ResponseBody - public ResponseEntity updateArticle(@PathVariable Integer id, @RequestBody Map body) { - Article article = articles.get(id); - if (article == null) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); - } - - if (body.containsKey("title")) { - article.setTitle(body.get("title")); - } - if (body.containsKey("content")) { - article.setContent(body.get("content")); - } - - article.setUpdatedAt(LocalDateTime.now()); - - return ResponseEntity.ok(article); - } - - @DeleteMapping("/articles/{id}") - @ResponseBody - public ResponseEntity deleteArticle(@PathVariable Integer id) { - if (!articles.containsKey(id)) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); - } - articles.remove(id); - return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); - } -} diff --git a/src/main/java/com/example/bcsd/controllers/ArticleController.java b/src/main/java/com/example/bcsd/controllers/ArticleController.java new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/com/example/bcsd/controllers/BoardController.java b/src/main/java/com/example/bcsd/controllers/BoardController.java new file mode 100644 index 00000000..f3a63672 --- /dev/null +++ b/src/main/java/com/example/bcsd/controllers/BoardController.java @@ -0,0 +1,17 @@ +package com.example.bcsd.controllers; + +import com.example.bcsd.services.boardService; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + + +@Controller +public class BoardController { + private final boardService boardService; + + public BoardController(boardService boardService) { + this.boardService = boardService; + } +} diff --git a/src/main/java/com/example/bcsd/daos/boardDao.java b/src/main/java/com/example/bcsd/daos/boardDao.java new file mode 100644 index 00000000..a7b013f1 --- /dev/null +++ b/src/main/java/com/example/bcsd/daos/boardDao.java @@ -0,0 +1,26 @@ +package com.example.bcsd.daos; + +import com.example.bcsd.models.Board; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class boardDao { + private final JdbcTemplate jdbcTemplate; + + public boardDao(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public String boardName(int boardId){ + String sql = "select name from board where id = ?"; + return jdbcTemplate.queryForObject(sql, String.class, boardId); + } + + public List articlesOnBoardId(int boardId){ + String sql = "select id from article where boardId = ?"; + return jdbcTemplate.queryForList(sql, Integer.class, boardId); + } +} diff --git a/src/main/java/com/example/bcsd/dtos/boardDto.java b/src/main/java/com/example/bcsd/dtos/boardDto.java new file mode 100644 index 00000000..0510bf44 --- /dev/null +++ b/src/main/java/com/example/bcsd/dtos/boardDto.java @@ -0,0 +1,30 @@ +package com.example.bcsd.dtos; + +public class boardDto { + private Long id; + private String name; + + public boardDto() { + } + + public boardDto(Long id, String title) { + this.id = id; + this.name = title; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return name; + } + + public void setTitle(String title) { + this.name = title; + } +} diff --git a/src/main/java/com/example/bcsd/models/Article.java b/src/main/java/com/example/bcsd/models/Article.java index af77c545..17b715db 100644 --- a/src/main/java/com/example/bcsd/models/Article.java +++ b/src/main/java/com/example/bcsd/models/Article.java @@ -1,57 +1,93 @@ package com.example.bcsd.models; +import java.time.LocalDateTime; + public class Article { - private final Long id; - private final String title; - private final Long authorId; - private final Long boardId; - private final String createdDate; - private final String content; - private final String modifiedDate; - - public Article(Long id, String title, Long authorId, Long boardId, String createdAt, String content, String modifiedDate) { - this.id = id; + private Integer id; + private Integer authorId; + private Integer boardId; + private String title; + private String content; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; + + public Article() { + this.createdAt = LocalDateTime.now(); + this.updatedAt = LocalDateTime.now(); + } + + public Article(Integer authorId, Integer boardId, String title, String content) { + this.authorId = authorId; + this.boardId = boardId; this.title = title; + this.content = content; + this.createdAt = LocalDateTime.now(); + this.updatedAt = LocalDateTime.now(); + } + + public Article(Integer id, Integer authorId, Integer boardId, String title, String content, LocalDateTime createdAt, LocalDateTime updatedAt) { + this.id = id; this.authorId = authorId; this.boardId = boardId; - this.createdDate = createdAt; + this.title = title; this.content = content; - this.modifiedDate = modifiedDate; + this.createdAt = createdAt; + this.updatedAt = updatedAt; } - public Long getId() { + public Integer getId() { return id; } - public String getTitle() { - return title; + public void setId(Integer id) { + this.id = id; } - public Article changeArticle(String title, String content, String modifiedDate) { - return new Article(id, title, authorId, boardId, createdDate, content, modifiedDate); + public Integer getAuthorId() { + return authorId; } - public Long getAuthorId() { - return authorId; + public void setAuthorId(Integer authorId) { + this.authorId = authorId; } - public Long getBoardId() { + public Integer getBoardId() { return boardId; } - public String getCreatedDate() { - return createdDate; + public void setBoardId(Integer boardId) { + this.boardId = boardId; } - public String getModifiedDate() { - return modifiedDate; + public String getTitle() { + return title; } - public Article updateModificationDate(String date) { - return new Article(id, title, authorId, boardId, createdDate, content, date); + public void setTitle(String title) { + this.title = title; } public String getContent() { return content; } + + public void setContent(String content) { + this.content = content; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } } \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Board.java b/src/main/java/com/example/bcsd/models/Board.java index 83d2c87f..ce7336c4 100644 --- a/src/main/java/com/example/bcsd/models/Board.java +++ b/src/main/java/com/example/bcsd/models/Board.java @@ -1,23 +1,28 @@ package com.example.bcsd.models; public class Board { - private final Long id; - private final String title; + + private Long id; + private String name; public Board(Long id, String title) { this.id = id; - this.title = title; + this.name = title; } - public String getTitle() { - return title; + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; } - public Board changeTitle(String title) { - return new Board(id, title); + public String getTitle() { + return name; } - public Long getId() { - return id; + public void setTitle(String title) { + this.name = title; } } \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Member.java b/src/main/java/com/example/bcsd/models/Member.java index 33bc893f..e87ec7d5 100644 --- a/src/main/java/com/example/bcsd/models/Member.java +++ b/src/main/java/com/example/bcsd/models/Member.java @@ -1,6 +1,7 @@ package com.example.bcsd.models; public class Member { + private Long id; private String name; private String email; @@ -17,27 +18,33 @@ public Long getId() { return id; } + public void setId(Long id) { + this.id = id; + } + public String getName() { return name; } - public Member changeName(String name) { - return new Member(id, name, email, password); + public void setName(String name) { + this.name = name; } public String getEmail() { return email; } - public Member changeEmail(String email) { - return new Member(id, name, email, password); + public void setEmail(String email) { + this.email = email; } public String getPassword() { return password; } - public Member changePassword(String password) { - return new Member(id, name, email, password); + public void setPassword(String password) { + this.password = password; } + + } \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/services/boardService.java b/src/main/java/com/example/bcsd/services/boardService.java new file mode 100644 index 00000000..559d7bd7 --- /dev/null +++ b/src/main/java/com/example/bcsd/services/boardService.java @@ -0,0 +1,23 @@ +package com.example.bcsd.services; + +import com.example.bcsd.daos.boardDao; +import com.example.bcsd.models.Board; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class boardService { + private final boardDao boardDao; + public boardService(boardDao boardDao) { + this.boardDao = boardDao; + } + + @Transactional(readOnly = true) + public List getBoards() { + } + +} From c85af65e52344c98c814f662fda7102017a35b6d Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Tue, 20 May 2025 15:06:50 +0900 Subject: [PATCH 08/22] =?UTF-8?q?board=20=EB=AA=A8=EB=8D=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/example/bcsd/daos/boardDao.java | 9 +++------ src/main/java/com/example/bcsd/models/Board.java | 10 +++++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/example/bcsd/daos/boardDao.java b/src/main/java/com/example/bcsd/daos/boardDao.java index a7b013f1..0b8ede29 100644 --- a/src/main/java/com/example/bcsd/daos/boardDao.java +++ b/src/main/java/com/example/bcsd/daos/boardDao.java @@ -14,13 +14,10 @@ public boardDao(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } - public String boardName(int boardId){ - String sql = "select name from board where id = ?"; + public String getboardName(int boardId){ + String sql = "SELECT name FROM board WHERE id = ?"; return jdbcTemplate.queryForObject(sql, String.class, boardId); } - public List articlesOnBoardId(int boardId){ - String sql = "select id from article where boardId = ?"; - return jdbcTemplate.queryForList(sql, Integer.class, boardId); - } + } diff --git a/src/main/java/com/example/bcsd/models/Board.java b/src/main/java/com/example/bcsd/models/Board.java index ce7336c4..62d445e5 100644 --- a/src/main/java/com/example/bcsd/models/Board.java +++ b/src/main/java/com/example/bcsd/models/Board.java @@ -5,9 +5,9 @@ public class Board { private Long id; private String name; - public Board(Long id, String title) { + public Board(Long id, String name) { this.id = id; - this.name = title; + this.name = name; } public Long getId() { @@ -18,11 +18,11 @@ public void setId(Long id) { this.id = id; } - public String getTitle() { + public String getName() { return name; } - public void setTitle(String title) { - this.name = title; + public void setName(String name) { + this.name = name; } } \ No newline at end of file From d229067cfdd366a0d93be0919e4b2be04a2f1d7a Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Tue, 20 May 2025 22:17:02 +0900 Subject: [PATCH 09/22] =?UTF-8?q?API=201=EB=B2=88=20=EA=B5=AC=ED=98=84,=20?= =?UTF-8?q?=EB=AF=B8=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bcsd/controllers/ArticleController.java | 120 ++++++++++++++++++ .../bcsd/controllers/BoardController.java | 17 ++- .../java/com/example/bcsd/daos/BoardDAO.java | 30 +++++ .../java/com/example/bcsd/daos/boardDao.java | 23 ---- .../dtos/{boardDto.java => BoardDTO.java} | 14 +- .../example/bcsd/services/BoardService.java | 25 ++++ .../example/bcsd/services/boardService.java | 23 ---- 7 files changed, 196 insertions(+), 56 deletions(-) create mode 100644 src/main/java/com/example/bcsd/daos/BoardDAO.java delete mode 100644 src/main/java/com/example/bcsd/daos/boardDao.java rename src/main/java/com/example/bcsd/dtos/{boardDto.java => BoardDTO.java} (54%) create mode 100644 src/main/java/com/example/bcsd/services/BoardService.java delete mode 100644 src/main/java/com/example/bcsd/services/boardService.java diff --git a/src/main/java/com/example/bcsd/controllers/ArticleController.java b/src/main/java/com/example/bcsd/controllers/ArticleController.java index e69de29b..132845c6 100644 --- a/src/main/java/com/example/bcsd/controllers/ArticleController.java +++ b/src/main/java/com/example/bcsd/controllers/ArticleController.java @@ -0,0 +1,120 @@ +package com.example.bcsd.controllers; + +import com.example.bcsd.models.Article; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDateTime; +import java.util.*; + +@Controller +public class ArticleController { + + private final Map articles = new HashMap<>(); + private Integer articleId = 1; + + @GetMapping("/posts") + public String showArticlesView( @RequestParam(name = "boardId", required = false) Integer boardId, Model model) { + + List
allArticles = new ArrayList<>(articles.values()); + allArticles.sort(Comparator.comparing(Article::getId)); + Map boardModelData = new HashMap<>(); + + if (boardId != null) { + boardModelData.put("id", boardId); + boardModelData.put("name", "게시판 " + boardId); + model.addAttribute("boardId", boardId); + } else { + boardModelData.put("name", "전체"); + } + + model.addAttribute("board", boardModelData); + model.addAttribute("articles", allArticles); + + return "boards"; + } + + @GetMapping("/articles") + @ResponseBody + public ResponseEntity> getArticlesByBoardId( + @RequestParam(name = "boardId", required = false) Integer boardId) { // boardId 파라미터는 받지만, 필터링에 사용되지 않음 + + List
allArticles = new ArrayList<>(articles.values()); + + allArticles.sort(Comparator.comparing(Article::getId)); + + return ResponseEntity.ok(allArticles); + } + + @PostMapping("/articles") + @ResponseBody + public ResponseEntity createArticle(@RequestBody Map body) { + try { + Integer authorId = Integer.parseInt(body.get("author_id")); + Integer boardId = Integer.parseInt(body.get("board_id")); + String title = body.get("title"); + String content = body.get("content"); + + if (title == null || content == null) { + return ResponseEntity.badRequest().body("Title or content is missing"); + } + + Article article = new Article(articleId, authorId, boardId, title, content, LocalDateTime.now(), LocalDateTime.now()); + articles.put(articleId, article); + articleId++; + + return ResponseEntity.status(HttpStatus.CREATED).body(article); + } catch (Exception e) { + return ResponseEntity.badRequest().body("Invalid input"); + } + } + + @GetMapping("/articles") + @ResponseBody + public ResponseEntity> getAllArticles() { + return ResponseEntity.ok(new ArrayList<>(articles.values())); + } + + @GetMapping("/articles/{id}") + @ResponseBody + public ResponseEntity getArticle(@PathVariable Integer id) { + Article article = articles.get(id); + if (article == null) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); + } + return ResponseEntity.ok(article); + } + + @PutMapping("/articles/{id}") + @ResponseBody + public ResponseEntity updateArticle(@PathVariable Integer id, @RequestBody Map body) { + Article article = articles.get(id); + if (article == null) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); + } + + if (body.containsKey("title")) { + article.setTitle(body.get("title")); + } + if (body.containsKey("content")) { + article.setContent(body.get("content")); + } + + article.setUpdatedAt(LocalDateTime.now()); + + return ResponseEntity.ok(article); + } + + @DeleteMapping("/articles/{id}") + @ResponseBody + public ResponseEntity deleteArticle(@PathVariable Integer id) { + if (!articles.containsKey(id)) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); + } + articles.remove(id); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } +} diff --git a/src/main/java/com/example/bcsd/controllers/BoardController.java b/src/main/java/com/example/bcsd/controllers/BoardController.java index f3a63672..98eecdc7 100644 --- a/src/main/java/com/example/bcsd/controllers/BoardController.java +++ b/src/main/java/com/example/bcsd/controllers/BoardController.java @@ -1,6 +1,9 @@ package com.example.bcsd.controllers; -import com.example.bcsd.services.boardService; +import ch.qos.logback.core.model.Model; +import com.example.bcsd.dtos.BoardDTO; +import com.example.bcsd.services.BoardService; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @@ -9,9 +12,17 @@ @Controller public class BoardController { - private final boardService boardService; + private final BoardService boardService; - public BoardController(boardService boardService) { + public BoardController(BoardService boardService) { this.boardService = boardService; } + + @GetMapping("/posts") + public ResponseEntity posts(@RequestParam("boardId") Long boardId, Model model) { + BoardDTO boardDto = boardService.getBoardsById(boardId); + + return new ResponseEntity<>(boardDto, HttpStatus.OK); + + } } diff --git a/src/main/java/com/example/bcsd/daos/BoardDAO.java b/src/main/java/com/example/bcsd/daos/BoardDAO.java new file mode 100644 index 00000000..9404601c --- /dev/null +++ b/src/main/java/com/example/bcsd/daos/BoardDAO.java @@ -0,0 +1,30 @@ +package com.example.bcsd.daos; + + +import com.example.bcsd.models.Board; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public class BoardDAO { + private final JdbcTemplate jdbcTemplate; + private final RowMapper boardMapper = (rs, rowNum) -> new Board( + rs.getLong("id"), + rs.getString("name") // DB의 'name' 컬럼과 매핑 + ); + + public BoardDAO(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public Optional findById(Long id) { + String sql = "select * from board where id = ?"; + Board board = (Board) jdbcTemplate.queryForObject(sql, boardMapper, id); + return Optional.ofNullable(board); + } + + +} diff --git a/src/main/java/com/example/bcsd/daos/boardDao.java b/src/main/java/com/example/bcsd/daos/boardDao.java deleted file mode 100644 index 0b8ede29..00000000 --- a/src/main/java/com/example/bcsd/daos/boardDao.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.bcsd.daos; - -import com.example.bcsd.models.Board; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public class boardDao { - private final JdbcTemplate jdbcTemplate; - - public boardDao(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - public String getboardName(int boardId){ - String sql = "SELECT name FROM board WHERE id = ?"; - return jdbcTemplate.queryForObject(sql, String.class, boardId); - } - - -} diff --git a/src/main/java/com/example/bcsd/dtos/boardDto.java b/src/main/java/com/example/bcsd/dtos/BoardDTO.java similarity index 54% rename from src/main/java/com/example/bcsd/dtos/boardDto.java rename to src/main/java/com/example/bcsd/dtos/BoardDTO.java index 0510bf44..6dde5e5c 100644 --- a/src/main/java/com/example/bcsd/dtos/boardDto.java +++ b/src/main/java/com/example/bcsd/dtos/BoardDTO.java @@ -1,15 +1,15 @@ package com.example.bcsd.dtos; -public class boardDto { +public class BoardDTO { private Long id; private String name; - public boardDto() { + public BoardDTO() { } - public boardDto(Long id, String title) { + public BoardDTO(Long id, String name) { this.id = id; - this.name = title; + this.name = name; } public Long getId() { @@ -20,11 +20,11 @@ public void setId(Long id) { this.id = id; } - public String getTitle() { + public String getName() { return name; } - public void setTitle(String title) { - this.name = title; + public void setName(String name) { + this.name = name; } } diff --git a/src/main/java/com/example/bcsd/services/BoardService.java b/src/main/java/com/example/bcsd/services/BoardService.java new file mode 100644 index 00000000..b41264da --- /dev/null +++ b/src/main/java/com/example/bcsd/services/BoardService.java @@ -0,0 +1,25 @@ +package com.example.bcsd.services; + +import com.example.bcsd.daos.BoardDAO; +import com.example.bcsd.dtos.BoardDTO; +import com.example.bcsd.models.Board; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +@Service +public class BoardService { + private final BoardDAO boardDao; + public BoardService(BoardDAO boardDao) { + this.boardDao = boardDao; + } + + @Transactional(readOnly = true) + public BoardDTO getBoardsById(Long id) { + Board board = boardDao.findById(id); + + return new BoardDTO(board.getId(), board.getName()); + } + +} diff --git a/src/main/java/com/example/bcsd/services/boardService.java b/src/main/java/com/example/bcsd/services/boardService.java deleted file mode 100644 index 559d7bd7..00000000 --- a/src/main/java/com/example/bcsd/services/boardService.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.bcsd.services; - -import com.example.bcsd.daos.boardDao; -import com.example.bcsd.models.Board; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Service -public class boardService { - private final boardDao boardDao; - public boardService(boardDao boardDao) { - this.boardDao = boardDao; - } - - @Transactional(readOnly = true) - public List getBoards() { - } - -} From 7dc0b8925ee26e59a5a112cd1eeb7ad85bb42b50 Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Sun, 25 May 2025 18:58:35 +0900 Subject: [PATCH 10/22] =?UTF-8?q?7=EC=A3=BC=EC=B0=A8=20=EC=99=84=EB=A3=8C?= =?UTF-8?q?=20=EB=B0=8F=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/bcsd/HelloController.java | 27 ---- .../bcsd/controllers/ArticleController.java | 123 ++++-------------- .../bcsd/controllers/BoardController.java | 28 ---- .../bcsd/controllers/PostController.java | 30 +++++ .../com/example/bcsd/daos/ArticleDAO.java | 56 ++++++++ .../java/com/example/bcsd/daos/BoardDAO.java | 14 +- .../java/com/example/bcsd/dtos/BoardDTO.java | 30 ----- .../exceptions/DataConflictException.java | 7 + .../exceptions/GlobalExceptionHandler.java | 29 +++++ .../exceptions/InvalidRequestException.java | 7 + .../exceptions/ResourceNotFoundException.java | 7 + .../java/com/example/bcsd/models/Article.java | 19 +-- .../java/com/example/bcsd/models/Board.java | 11 +- .../java/com/example/bcsd/models/Member.java | 8 +- .../example/bcsd/services/BoardService.java | 25 ---- .../example/bcsd/services/PostService.java | 50 +++++++ src/main/resources/templates/boards.html | 14 -- src/main/resources/templates/posts.html | 17 ++- 18 files changed, 245 insertions(+), 257 deletions(-) delete mode 100644 src/main/java/com/example/bcsd/HelloController.java delete mode 100644 src/main/java/com/example/bcsd/controllers/BoardController.java create mode 100644 src/main/java/com/example/bcsd/controllers/PostController.java create mode 100644 src/main/java/com/example/bcsd/daos/ArticleDAO.java delete mode 100644 src/main/java/com/example/bcsd/dtos/BoardDTO.java create mode 100644 src/main/java/com/example/bcsd/exceptions/DataConflictException.java create mode 100644 src/main/java/com/example/bcsd/exceptions/GlobalExceptionHandler.java create mode 100644 src/main/java/com/example/bcsd/exceptions/InvalidRequestException.java create mode 100644 src/main/java/com/example/bcsd/exceptions/ResourceNotFoundException.java delete mode 100644 src/main/java/com/example/bcsd/services/BoardService.java create mode 100644 src/main/java/com/example/bcsd/services/PostService.java delete mode 100644 src/main/resources/templates/boards.html diff --git a/src/main/java/com/example/bcsd/HelloController.java b/src/main/java/com/example/bcsd/HelloController.java deleted file mode 100644 index c1b705d5..00000000 --- a/src/main/java/com/example/bcsd/HelloController.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.example.bcsd; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -import java.util.HashMap; -import java.util.Map; - -@Controller -public class HelloController { - - @ResponseBody - @GetMapping("/introduce") - public String introduce(@RequestParam(name = "name", required = false, defaultValue = "홍길동") String name) { - return "안녕하세요 제 이름은 " + name + "입니다!"; - } - @ResponseBody - @GetMapping("/json") - public Map json() { - Map map = new HashMap<>(); - map.put("age", 26); - map.put("name", "허준기"); - return map; - } -} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/controllers/ArticleController.java b/src/main/java/com/example/bcsd/controllers/ArticleController.java index 132845c6..c2f476e4 100644 --- a/src/main/java/com/example/bcsd/controllers/ArticleController.java +++ b/src/main/java/com/example/bcsd/controllers/ArticleController.java @@ -1,120 +1,47 @@ package com.example.bcsd.controllers; import com.example.bcsd.models.Article; +import com.example.bcsd.services.PostService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; -import java.time.LocalDateTime; -import java.util.*; +import java.util.List; -@Controller +@RestController +@RequestMapping("/articles") public class ArticleController { + private final PostService postService; - private final Map articles = new HashMap<>(); - private Integer articleId = 1; - - @GetMapping("/posts") - public String showArticlesView( @RequestParam(name = "boardId", required = false) Integer boardId, Model model) { - - List
allArticles = new ArrayList<>(articles.values()); - allArticles.sort(Comparator.comparing(Article::getId)); - Map boardModelData = new HashMap<>(); - - if (boardId != null) { - boardModelData.put("id", boardId); - boardModelData.put("name", "게시판 " + boardId); - model.addAttribute("boardId", boardId); - } else { - boardModelData.put("name", "전체"); - } - - model.addAttribute("board", boardModelData); - model.addAttribute("articles", allArticles); - - return "boards"; - } - - @GetMapping("/articles") - @ResponseBody - public ResponseEntity> getArticlesByBoardId( - @RequestParam(name = "boardId", required = false) Integer boardId) { // boardId 파라미터는 받지만, 필터링에 사용되지 않음 - - List
allArticles = new ArrayList<>(articles.values()); - - allArticles.sort(Comparator.comparing(Article::getId)); - - return ResponseEntity.ok(allArticles); + public ArticleController(PostService postService) { + this.postService = postService; } - @PostMapping("/articles") - @ResponseBody - public ResponseEntity createArticle(@RequestBody Map body) { - try { - Integer authorId = Integer.parseInt(body.get("author_id")); - Integer boardId = Integer.parseInt(body.get("board_id")); - String title = body.get("title"); - String content = body.get("content"); - - if (title == null || content == null) { - return ResponseEntity.badRequest().body("Title or content is missing"); - } - - Article article = new Article(articleId, authorId, boardId, title, content, LocalDateTime.now(), LocalDateTime.now()); - articles.put(articleId, article); - articleId++; - - return ResponseEntity.status(HttpStatus.CREATED).body(article); - } catch (Exception e) { - return ResponseEntity.badRequest().body("Invalid input"); - } + @GetMapping + public List
getArticlesByBoard(@RequestParam("boardId") int boardId) { + return postService.getArticlesByBoard(boardId); } - @GetMapping("/articles") - @ResponseBody - public ResponseEntity> getAllArticles() { - return ResponseEntity.ok(new ArrayList<>(articles.values())); + @GetMapping("/{id}") + public Article getArticle(@PathVariable int id) { + return postService.getArticleById(id); } - @GetMapping("/articles/{id}") - @ResponseBody - public ResponseEntity getArticle(@PathVariable Integer id) { - Article article = articles.get(id); - if (article == null) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); - } - return ResponseEntity.ok(article); + @PostMapping + public ResponseEntity createArticle(@RequestBody Article article) { + postService.createArticle(article); + return ResponseEntity.status(HttpStatus.CREATED).build(); } - @PutMapping("/articles/{id}") - @ResponseBody - public ResponseEntity updateArticle(@PathVariable Integer id, @RequestBody Map body) { - Article article = articles.get(id); - if (article == null) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); - } - - if (body.containsKey("title")) { - article.setTitle(body.get("title")); - } - if (body.containsKey("content")) { - article.setContent(body.get("content")); - } - - article.setUpdatedAt(LocalDateTime.now()); - - return ResponseEntity.ok(article); + @PutMapping("/{id}") + public ResponseEntity updateArticle(@PathVariable int id, @RequestBody Article article) { + postService.updateArticle(id, article); + return ResponseEntity.ok().build(); } - @DeleteMapping("/articles/{id}") - @ResponseBody - public ResponseEntity deleteArticle(@PathVariable Integer id) { - if (!articles.containsKey(id)) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found"); - } - articles.remove(id); - return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + @DeleteMapping("/{id}") + public ResponseEntity deleteArticle(@PathVariable int id) { + postService.deleteArticle(id); + return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/com/example/bcsd/controllers/BoardController.java b/src/main/java/com/example/bcsd/controllers/BoardController.java deleted file mode 100644 index 98eecdc7..00000000 --- a/src/main/java/com/example/bcsd/controllers/BoardController.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.example.bcsd.controllers; - -import ch.qos.logback.core.model.Model; -import com.example.bcsd.dtos.BoardDTO; -import com.example.bcsd.services.BoardService; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; - - -@Controller -public class BoardController { - private final BoardService boardService; - - public BoardController(BoardService boardService) { - this.boardService = boardService; - } - - @GetMapping("/posts") - public ResponseEntity posts(@RequestParam("boardId") Long boardId, Model model) { - BoardDTO boardDto = boardService.getBoardsById(boardId); - - return new ResponseEntity<>(boardDto, HttpStatus.OK); - - } -} diff --git a/src/main/java/com/example/bcsd/controllers/PostController.java b/src/main/java/com/example/bcsd/controllers/PostController.java new file mode 100644 index 00000000..4db11e40 --- /dev/null +++ b/src/main/java/com/example/bcsd/controllers/PostController.java @@ -0,0 +1,30 @@ +package com.example.bcsd.controllers; + +import com.example.bcsd.models.Article; +import com.example.bcsd.services.PostService; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +@Controller +public class PostController { + private final PostService postService; + + public PostController(PostService postService) { + this.postService = postService; + } + + @GetMapping("/posts") + public String getPosts(@RequestParam int boardId, Model model) { + List
articles = postService.getArticlesByBoard(boardId); + String boardName = postService.getBoardName(boardId); + + model.addAttribute("boardName", boardName); + model.addAttribute("articles", articles); + return "posts"; + } +} diff --git a/src/main/java/com/example/bcsd/daos/ArticleDAO.java b/src/main/java/com/example/bcsd/daos/ArticleDAO.java new file mode 100644 index 00000000..f9ebfe5f --- /dev/null +++ b/src/main/java/com/example/bcsd/daos/ArticleDAO.java @@ -0,0 +1,56 @@ +package com.example.bcsd.daos; + +import com.example.bcsd.models.Article; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class ArticleDAO { + private final JdbcTemplate jdbcTemplate; + + public ArticleDAO(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public List
findByBoardId(int boardId) { + String sql = "SELECT * FROM article WHERE board_id = ?"; + return jdbcTemplate.query(sql, articleRowMapper(), boardId); + } + + public Article findById(int id) { + String sql = "SELECT * FROM article WHERE id = ?"; + return jdbcTemplate.queryForObject(sql, articleRowMapper(), id); + } + + public void insert(Article article) { + String sql = "INSERT INTO article (author_id, board_id, title, content) VALUES (?, ?, ?, ?)"; + jdbcTemplate.update(sql, article.getAuthorId(), article.getBoardId(), article.getTitle(), article.getContent()); + } + + public void update(int id, Article article) { + String sql = "UPDATE article SET board_id = ?, title = ?, content = ?, modified_date = NOW() WHERE id = ?"; + jdbcTemplate.update(sql, article.getBoardId(), article.getTitle(), article.getContent(), id); + } + + public void delete(int id) { + String sql = "DELETE FROM article WHERE id = ?"; + jdbcTemplate.update(sql, id); + } + + private RowMapper
articleRowMapper() { + return (rs, rowNum) -> { + Article dto = new Article(); + dto.setId(rs.getInt("id")); + dto.setAuthorId(rs.getInt("author_id")); + dto.setBoardId(rs.getInt("board_id")); + dto.setTitle(rs.getString("title")); + dto.setContent(rs.getString("content")); + dto.setCreatedAt(rs.getTimestamp("created_date").toLocalDateTime()); + dto.setUpdatedAt(rs.getTimestamp("modified_date").toLocalDateTime()); + return dto; + }; + } +} diff --git a/src/main/java/com/example/bcsd/daos/BoardDAO.java b/src/main/java/com/example/bcsd/daos/BoardDAO.java index 9404601c..8769a30c 100644 --- a/src/main/java/com/example/bcsd/daos/BoardDAO.java +++ b/src/main/java/com/example/bcsd/daos/BoardDAO.java @@ -2,6 +2,7 @@ import com.example.bcsd.models.Board; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; @@ -11,20 +12,13 @@ @Repository public class BoardDAO { private final JdbcTemplate jdbcTemplate; - private final RowMapper boardMapper = (rs, rowNum) -> new Board( - rs.getLong("id"), - rs.getString("name") // DB의 'name' 컬럼과 매핑 - ); public BoardDAO(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } - public Optional findById(Long id) { - String sql = "select * from board where id = ?"; - Board board = (Board) jdbcTemplate.queryForObject(sql, boardMapper, id); - return Optional.ofNullable(board); + public String findNameById(int id) { + String sql = "SELECT name FROM board WHERE id = ?"; + return jdbcTemplate.queryForObject(sql, String.class, id); } - - } diff --git a/src/main/java/com/example/bcsd/dtos/BoardDTO.java b/src/main/java/com/example/bcsd/dtos/BoardDTO.java deleted file mode 100644 index 6dde5e5c..00000000 --- a/src/main/java/com/example/bcsd/dtos/BoardDTO.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.example.bcsd.dtos; - -public class BoardDTO { - private Long id; - private String name; - - public BoardDTO() { - } - - public BoardDTO(Long id, String name) { - this.id = id; - this.name = name; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} diff --git a/src/main/java/com/example/bcsd/exceptions/DataConflictException.java b/src/main/java/com/example/bcsd/exceptions/DataConflictException.java new file mode 100644 index 00000000..9b526837 --- /dev/null +++ b/src/main/java/com/example/bcsd/exceptions/DataConflictException.java @@ -0,0 +1,7 @@ +package com.example.bcsd.exceptions; + +public class DataConflictException extends RuntimeException { + public DataConflictException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/exceptions/GlobalExceptionHandler.java b/src/main/java/com/example/bcsd/exceptions/GlobalExceptionHandler.java new file mode 100644 index 00000000..84942b65 --- /dev/null +++ b/src/main/java/com/example/bcsd/exceptions/GlobalExceptionHandler.java @@ -0,0 +1,29 @@ +package com.example.bcsd.exceptions; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(ResourceNotFoundException.class) + public ResponseEntity handleNotFound(ResourceNotFoundException ex) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); + } + + @ExceptionHandler(DataConflictException.class) + public ResponseEntity handleConflict(DataConflictException ex) { + return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage()); + } + + @ExceptionHandler(InvalidRequestException.class) + public ResponseEntity handleBadRequest(InvalidRequestException ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage()); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity handleOther(Exception ex) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("서버 오류: " + ex.getMessage()); + } +} diff --git a/src/main/java/com/example/bcsd/exceptions/InvalidRequestException.java b/src/main/java/com/example/bcsd/exceptions/InvalidRequestException.java new file mode 100644 index 00000000..2f157af1 --- /dev/null +++ b/src/main/java/com/example/bcsd/exceptions/InvalidRequestException.java @@ -0,0 +1,7 @@ +package com.example.bcsd.exceptions; + +public class InvalidRequestException extends RuntimeException { + public InvalidRequestException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/exceptions/ResourceNotFoundException.java b/src/main/java/com/example/bcsd/exceptions/ResourceNotFoundException.java new file mode 100644 index 00000000..c2106f33 --- /dev/null +++ b/src/main/java/com/example/bcsd/exceptions/ResourceNotFoundException.java @@ -0,0 +1,7 @@ +package com.example.bcsd.exceptions; + +public class ResourceNotFoundException extends RuntimeException{ + public ResourceNotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/com/example/bcsd/models/Article.java b/src/main/java/com/example/bcsd/models/Article.java index 17b715db..35a78831 100644 --- a/src/main/java/com/example/bcsd/models/Article.java +++ b/src/main/java/com/example/bcsd/models/Article.java @@ -3,9 +3,9 @@ import java.time.LocalDateTime; public class Article { - private Integer id; - private Integer authorId; - private Integer boardId; + private int id; + private int authorId; + private int boardId; private String title; private String content; private LocalDateTime createdAt; @@ -35,7 +35,10 @@ public Article(Integer id, Integer authorId, Integer boardId, String title, Stri this.updatedAt = updatedAt; } - public Integer getId() { + public Article(int id, String title) { + } + + public int getId() { return id; } @@ -43,19 +46,19 @@ public void setId(Integer id) { this.id = id; } - public Integer getAuthorId() { + public int getAuthorId() { return authorId; } - public void setAuthorId(Integer authorId) { + public void setAuthorId(int authorId) { this.authorId = authorId; } - public Integer getBoardId() { + public int getBoardId() { return boardId; } - public void setBoardId(Integer boardId) { + public void setBoardId(int boardId) { this.boardId = boardId; } diff --git a/src/main/java/com/example/bcsd/models/Board.java b/src/main/java/com/example/bcsd/models/Board.java index 62d445e5..b35b2e17 100644 --- a/src/main/java/com/example/bcsd/models/Board.java +++ b/src/main/java/com/example/bcsd/models/Board.java @@ -2,19 +2,22 @@ public class Board { - private Long id; + private int id; private String name; + public Board() { - public Board(Long id, String name) { + } + + public Board(int id, String name) { this.id = id; this.name = name; } - public Long getId() { + public int getId() { return id; } - public void setId(Long id) { + public void setId(int id) { this.id = id; } diff --git a/src/main/java/com/example/bcsd/models/Member.java b/src/main/java/com/example/bcsd/models/Member.java index e87ec7d5..e8e008fc 100644 --- a/src/main/java/com/example/bcsd/models/Member.java +++ b/src/main/java/com/example/bcsd/models/Member.java @@ -2,23 +2,23 @@ public class Member { - private Long id; + private int id; private String name; private String email; private String password; - public Member(Long id, String name, String email, String password) { + public Member(int id, String name, String email, String password) { this.id = id; this.name = name; this.email = email; this.password = password; } - public Long getId() { + public int getId() { return id; } - public void setId(Long id) { + public void setId(int id) { this.id = id; } diff --git a/src/main/java/com/example/bcsd/services/BoardService.java b/src/main/java/com/example/bcsd/services/BoardService.java deleted file mode 100644 index b41264da..00000000 --- a/src/main/java/com/example/bcsd/services/BoardService.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.example.bcsd.services; - -import com.example.bcsd.daos.BoardDAO; -import com.example.bcsd.dtos.BoardDTO; -import com.example.bcsd.models.Board; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Optional; - -@Service -public class BoardService { - private final BoardDAO boardDao; - public BoardService(BoardDAO boardDao) { - this.boardDao = boardDao; - } - - @Transactional(readOnly = true) - public BoardDTO getBoardsById(Long id) { - Board board = boardDao.findById(id); - - return new BoardDTO(board.getId(), board.getName()); - } - -} diff --git a/src/main/java/com/example/bcsd/services/PostService.java b/src/main/java/com/example/bcsd/services/PostService.java new file mode 100644 index 00000000..cf9b8811 --- /dev/null +++ b/src/main/java/com/example/bcsd/services/PostService.java @@ -0,0 +1,50 @@ +package com.example.bcsd.services; + +import com.example.bcsd.daos.ArticleDAO; +import com.example.bcsd.daos.BoardDAO; +import com.example.bcsd.models.Article; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +public class PostService { + private final ArticleDAO articleDao; + private final BoardDAO boardDao; + + public PostService( ArticleDAO articleDao, BoardDAO boardDao) { + this.articleDao = articleDao; + this.boardDao = boardDao; + } + + @Transactional(readOnly = true) + public List
getArticlesByBoard(int boardId) { + return articleDao.findByBoardId(boardId); + } + + @Transactional(readOnly = true) + public String getBoardName(int boardId) { + return boardDao.findNameById(boardId); + } + @Transactional(readOnly = true) + public Article getArticleById(int id) { + return articleDao.findById(id); + } + + @Transactional + public void createArticle(Article article) { + articleDao.insert(article); + } + + @Transactional + public void updateArticle(int id, Article article) { + articleDao.update(id, article); + } + + @Transactional + public void deleteArticle(int id) { + articleDao.delete(id); + } + +} diff --git a/src/main/resources/templates/boards.html b/src/main/resources/templates/boards.html deleted file mode 100644 index f4179c88..00000000 --- a/src/main/resources/templates/boards.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - Board Posts - - -

Board:

- - - \ No newline at end of file diff --git a/src/main/resources/templates/posts.html b/src/main/resources/templates/posts.html index 44492e66..948e69b2 100644 --- a/src/main/resources/templates/posts.html +++ b/src/main/resources/templates/posts.html @@ -2,15 +2,14 @@ - - 게시판 + Board Posts -

-
-

- -

-
+

+
    +
  • + +
  • +
- \ No newline at end of file + From 3a3a5be87e68ca55fc96e1dedceccce80453199f Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Sun, 25 May 2025 19:15:51 +0900 Subject: [PATCH 11/22] =?UTF-8?q?=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/bcsd/services/PostService.java | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/bcsd/services/PostService.java b/src/main/java/com/example/bcsd/services/PostService.java index cf9b8811..0175cf0f 100644 --- a/src/main/java/com/example/bcsd/services/PostService.java +++ b/src/main/java/com/example/bcsd/services/PostService.java @@ -2,7 +2,10 @@ import com.example.bcsd.daos.ArticleDAO; import com.example.bcsd.daos.BoardDAO; +import com.example.bcsd.exceptions.InvalidRequestException; +import com.example.bcsd.exceptions.ResourceNotFoundException; import com.example.bcsd.models.Article; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -20,30 +23,76 @@ public PostService( ArticleDAO articleDao, BoardDAO boardDao) { @Transactional(readOnly = true) public List
getArticlesByBoard(int boardId) { + try { + boardDao.findNameById(boardId); + } catch (EmptyResultDataAccessException e) { + throw new ResourceNotFoundException("ID가 " + boardId + "인 게시판을 찾을 수 없습니다."); + } return articleDao.findByBoardId(boardId); } @Transactional(readOnly = true) public String getBoardName(int boardId) { - return boardDao.findNameById(boardId); + try { + return boardDao.findNameById(boardId); + } catch (EmptyResultDataAccessException e) { + throw new ResourceNotFoundException("ID가 " + boardId + "인 게시판을 찾을 수 없습니다."); + } } @Transactional(readOnly = true) public Article getArticleById(int id) { - return articleDao.findById(id); + try { + return articleDao.findById(id); + } catch (EmptyResultDataAccessException e) { + throw new ResourceNotFoundException("ID가 " + id + "인 게시물을 찾을 수 없습니다."); + } } @Transactional public void createArticle(Article article) { + if (article.getAuthorId() == 0 || article.getBoardId() == 0 || + article.getTitle() == null || article.getTitle().isBlank() || + article.getContent() == null || article.getContent().isBlank()) { + throw new InvalidRequestException("게시물 생성 요청 시 필수 값이 누락되었습니다. (authorId, boardId, title, content)"); + } + +// try { //멤버가 있는지 없는지 검사함. 아직 작성전 +// memberDao.findById(article.getAuthorId()); +// } catch (EmptyResultDataAccessException e) { +// throw new InvalidRequestException("ID가 " + article.getAuthorId() + "인 사용자를 찾을 수 없습니다."); +// } + + try { + boardDao.findNameById(article.getBoardId()); + } catch (EmptyResultDataAccessException e) { + throw new InvalidRequestException("ID가 " + article.getBoardId() + "인 게시판을 찾을 수 없습니다."); + } + articleDao.insert(article); } @Transactional public void updateArticle(int id, Article article) { + Article existingArticle = getArticleById(id); + if (article.getBoardId() != 0) { // boardId가 업데이트 요청에 포함된 경우에만 확인 + try { + boardDao.findNameById(article.getBoardId()); + } catch (EmptyResultDataAccessException e) { + throw new InvalidRequestException("ID가 " + article.getBoardId() + "인 게시판을 찾을 수 없습니다."); + } + } + if (article.getTitle() != null && article.getTitle().isBlank()) { + throw new InvalidRequestException("게시물 제목은 비워둘 수 없습니다."); + } + if (article.getContent() != null && article.getContent().isBlank()) { + throw new InvalidRequestException("게시물 내용은 비워둘 수 없습니다."); + } articleDao.update(id, article); } @Transactional public void deleteArticle(int id) { + getArticleById(id); //없으면 예외발생 articleDao.delete(id); } From 31c7db209347f5aa231e058297967f5b15ba38b5 Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Sun, 25 May 2025 19:27:57 +0900 Subject: [PATCH 12/22] =?UTF-8?q?MemberDao=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/bcsd/daos/MemberDAO.java | 57 +++++++++++++++++++ .../java/com/example/bcsd/models/Member.java | 4 ++ 2 files changed, 61 insertions(+) create mode 100644 src/main/java/com/example/bcsd/daos/MemberDAO.java diff --git a/src/main/java/com/example/bcsd/daos/MemberDAO.java b/src/main/java/com/example/bcsd/daos/MemberDAO.java new file mode 100644 index 00000000..753ea22d --- /dev/null +++ b/src/main/java/com/example/bcsd/daos/MemberDAO.java @@ -0,0 +1,57 @@ +package com.example.bcsd.daos; + +import com.example.bcsd.models.Member; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class MemberDAO { + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public MemberDAO(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + private RowMapper memberRowMapper() { + return (rs, rowNum) -> { + Member dto = new Member(); + dto.setId(rs.getInt("id")); + dto.setEmail(rs.getString("email")); + dto.setName(rs.getString("name")); + dto.setPassword(rs.getString("password")); + return dto; + }; + } + + public Member findById(int id) throws EmptyResultDataAccessException { + String sql = "SELECT * FROM Member WHERE id = ?"; + return jdbcTemplate.queryForObject(sql, memberRowMapper(), id); + } + + public List findAll() { + String sql = "SELECT * FROM Member"; + return jdbcTemplate.query(sql, memberRowMapper()); + } + + public void insert(Member member) { + String sql = "INSERT INTO Member (name, email, password) VALUES (?, ?, ?)"; + jdbcTemplate.update(sql, member.getName(), member.getEmail(), member.getPassword()); + } + + public void updateMember(Member member) { + String sql = "UPDATE Member SET name = ?, email = ?, password = ? WHERE id = ?"; + jdbcTemplate.update(sql, member.getName(), member.getEmail(), member.getPassword(), member.getId()); + } + + public void deleteMember(int id) { + String sql = "DELETE FROM Member WHERE id = ?"; + jdbcTemplate.update(sql, id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Member.java b/src/main/java/com/example/bcsd/models/Member.java index e8e008fc..75391feb 100644 --- a/src/main/java/com/example/bcsd/models/Member.java +++ b/src/main/java/com/example/bcsd/models/Member.java @@ -14,6 +14,10 @@ public Member(int id, String name, String email, String password) { this.password = password; } + public Member() { + + } + public int getId() { return id; } From 8e653f1207d639951cc9bc943ada5c0054ac006b Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Sun, 25 May 2025 20:42:25 +0900 Subject: [PATCH 13/22] =?UTF-8?q?member=EC=97=90=20=EA=B4=80=ED=95=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1=20=EB=B0=8F=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bcsd/controllers/MemberController.java | 55 ++++++++++ .../com/example/bcsd/daos/ArticleDAO.java | 6 ++ .../java/com/example/bcsd/daos/MemberDAO.java | 10 ++ .../example/bcsd/services/MemberService.java | 102 ++++++++++++++++++ .../example/bcsd/services/PostService.java | 17 +-- 5 files changed, 183 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/example/bcsd/controllers/MemberController.java create mode 100644 src/main/java/com/example/bcsd/services/MemberService.java diff --git a/src/main/java/com/example/bcsd/controllers/MemberController.java b/src/main/java/com/example/bcsd/controllers/MemberController.java new file mode 100644 index 00000000..85cf68bf --- /dev/null +++ b/src/main/java/com/example/bcsd/controllers/MemberController.java @@ -0,0 +1,55 @@ +package com.example.bcsd.controllers; + +import com.example.bcsd.models.Member; +import com.example.bcsd.services.MemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/members") +public class MemberController { + + private final MemberService memberService; + + @Autowired + public MemberController(MemberService memberService) { + this.memberService = memberService; + } + + @PostMapping + public ResponseEntity createMember(@RequestBody Member member) { + Member createdMember = memberService.createMember(member); + // 생성된 리소스의 URI를 반환하는 것이 RESTful API 디자인에 더 적합할 수 있으나, + // 여기서는 생성된 객체와 함께 201 CREATED를 반환합니다. + // 또는 ResponseEntity와 함께 Location 헤더를 사용할 수 있습니다. + return ResponseEntity.status(HttpStatus.CREATED).body(createdMember); + } + + @GetMapping("/{id}") + public ResponseEntity getMemberById(@PathVariable int id) { + Member member = memberService.getMemberById(id); + return ResponseEntity.ok(member); + } + + @GetMapping + public ResponseEntity> getAllMembers() { + List members = memberService.getAllMembers(); + return ResponseEntity.ok(members); + } + + @PutMapping("/{id}") + public ResponseEntity updateMember(@PathVariable int id, @RequestBody Member member) { + memberService.updateMember(id, member); + return ResponseEntity.ok().build(); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteMember(@PathVariable int id) { + memberService.deleteMember(id); + return ResponseEntity.noContent().build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/daos/ArticleDAO.java b/src/main/java/com/example/bcsd/daos/ArticleDAO.java index f9ebfe5f..42315d97 100644 --- a/src/main/java/com/example/bcsd/daos/ArticleDAO.java +++ b/src/main/java/com/example/bcsd/daos/ArticleDAO.java @@ -40,6 +40,12 @@ public void delete(int id) { jdbcTemplate.update(sql, id); } + public int countByAuthorId(int authorId) { + String sql = "SELECT COUNT(*) FROM article WHERE author_id = ?"; + Integer count = jdbcTemplate.queryForObject(sql, Integer.class, authorId); + return (count != null) ? count : 0; + } + private RowMapper
articleRowMapper() { return (rs, rowNum) -> { Article dto = new Article(); diff --git a/src/main/java/com/example/bcsd/daos/MemberDAO.java b/src/main/java/com/example/bcsd/daos/MemberDAO.java index 753ea22d..cef78148 100644 --- a/src/main/java/com/example/bcsd/daos/MemberDAO.java +++ b/src/main/java/com/example/bcsd/daos/MemberDAO.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Optional; @Repository public class MemberDAO { @@ -54,4 +55,13 @@ public void deleteMember(int id) { String sql = "DELETE FROM Member WHERE id = ?"; jdbcTemplate.update(sql, id); } + + public Optional findByEmail(String email) { + String sql = "SELECT * FROM Member WHERE email = ?"; + try { + return Optional.ofNullable(jdbcTemplate.queryForObject(sql, memberRowMapper(), email)); + } catch (EmptyResultDataAccessException e) { + return Optional.empty(); + } + } } \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/services/MemberService.java b/src/main/java/com/example/bcsd/services/MemberService.java new file mode 100644 index 00000000..17a417f7 --- /dev/null +++ b/src/main/java/com/example/bcsd/services/MemberService.java @@ -0,0 +1,102 @@ +package com.example.bcsd.services; + +import com.example.bcsd.daos.ArticleDAO; +import com.example.bcsd.daos.MemberDAO; +// (향후 과제 기능 구현 시 필요) 게시물 존재 여부 확인을 위해 ArticleDAO 또는 관련 서비스 필요 +// import com.example.bcsd.daos.ArticleDAO; +import com.example.bcsd.exceptions.DataConflictException; +import com.example.bcsd.exceptions.InvalidRequestException; +import com.example.bcsd.exceptions.ResourceNotFoundException; +import com.example.bcsd.models.Member; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; + +@Service +public class MemberService { + + private final MemberDAO memberDao; + private final ArticleDAO articleDao; + + @Autowired + public MemberService(MemberDAO memberDao, ArticleDAO articleDao) { + this.memberDao = memberDao; + this.articleDao = articleDao; + } + + @Transactional + public Member createMember(Member member) { + if (member.getName() == null || member.getName().isBlank() || + member.getEmail() == null || member.getEmail().isBlank() || + member.getPassword() == null || member.getPassword().isBlank()) { + throw new InvalidRequestException("사용자 생성 요청 시 필수 값이 누락되었습니다. (name, email, password)"); + } + + memberDao.findByEmail(member.getEmail()).ifPresent(m -> { + throw new DataConflictException("이미 사용 중인 이메일입니다: " + member.getEmail()); + }); + + memberDao.insert(member); + return member; + } + + @Transactional(readOnly = true) + public Member getMemberById(int id) { + try { + return memberDao.findById(id); + } catch (EmptyResultDataAccessException e) { + throw new ResourceNotFoundException("ID가 " + id + "인 사용자를 찾을 수 없습니다."); + } + } + + @Transactional(readOnly = true) + public List getAllMembers() { + return memberDao.findAll(); + } + + @Transactional + public void updateMember(int id, Member memberUpdateData) { + Member existingMember = getMemberById(id); // 존재하지 않으면 예외 + + if (memberUpdateData.getName() != null && memberUpdateData.getName().isBlank()) { + throw new InvalidRequestException("사용자 이름은 비워둘 수 없습니다."); + } + if (memberUpdateData.getEmail() != null && memberUpdateData.getEmail().isBlank()) { + throw new InvalidRequestException("이메일은 비워둘 수 없습니다."); + } + if (memberUpdateData.getPassword() != null && memberUpdateData.getPassword().isBlank()) { + throw new InvalidRequestException("비밀번호는 비워둘 수 없습니다."); + } + + if (memberUpdateData.getEmail() != null && !memberUpdateData.getEmail().equalsIgnoreCase(existingMember.getEmail())) { + Optional memberWithNewEmail = memberDao.findByEmail(memberUpdateData.getEmail()); + if (memberWithNewEmail.isPresent() && memberWithNewEmail.get().getId() != id) { + throw new DataConflictException("이미 다른 사용자가 사용 중인 이메일입니다: " + memberUpdateData.getEmail()); + } + existingMember.setEmail(memberUpdateData.getEmail()); + } + + if (memberUpdateData.getName() != null && !memberUpdateData.getName().isBlank()) { + existingMember.setName(memberUpdateData.getName()); + } + if (memberUpdateData.getPassword() != null && !memberUpdateData.getPassword().isBlank()) { + existingMember.setPassword(memberUpdateData.getPassword()); + } + + memberDao.updateMember(existingMember); + } + + @Transactional + public void deleteMember(int id) { + getMemberById(id); + + if (articleDao.countByAuthorId(id) > 0) { + throw new InvalidRequestException("ID가 " + id + "인 사용자는 작성한 게시물이 있어 삭제할 수 없습니다."); + } + memberDao.deleteMember(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/services/PostService.java b/src/main/java/com/example/bcsd/services/PostService.java index 0175cf0f..f799067c 100644 --- a/src/main/java/com/example/bcsd/services/PostService.java +++ b/src/main/java/com/example/bcsd/services/PostService.java @@ -2,6 +2,7 @@ import com.example.bcsd.daos.ArticleDAO; import com.example.bcsd.daos.BoardDAO; +import com.example.bcsd.daos.MemberDAO; import com.example.bcsd.exceptions.InvalidRequestException; import com.example.bcsd.exceptions.ResourceNotFoundException; import com.example.bcsd.models.Article; @@ -15,10 +16,12 @@ public class PostService { private final ArticleDAO articleDao; private final BoardDAO boardDao; + private final MemberDAO memberDao; - public PostService( ArticleDAO articleDao, BoardDAO boardDao) { + public PostService(ArticleDAO articleDao, BoardDAO boardDao, MemberDAO memberDao) { this.articleDao = articleDao; this.boardDao = boardDao; + this.memberDao = memberDao; } @Transactional(readOnly = true) @@ -56,11 +59,11 @@ public void createArticle(Article article) { throw new InvalidRequestException("게시물 생성 요청 시 필수 값이 누락되었습니다. (authorId, boardId, title, content)"); } -// try { //멤버가 있는지 없는지 검사함. 아직 작성전 -// memberDao.findById(article.getAuthorId()); -// } catch (EmptyResultDataAccessException e) { -// throw new InvalidRequestException("ID가 " + article.getAuthorId() + "인 사용자를 찾을 수 없습니다."); -// } + try { //멤버가 있는지 없는지 검사함. 아직 작성 + memberDao.findById(article.getAuthorId()); + } catch (EmptyResultDataAccessException e) { + throw new InvalidRequestException("ID가 " + article.getAuthorId() + "인 사용자를 찾을 수 없습니다."); + } try { boardDao.findNameById(article.getBoardId()); @@ -73,7 +76,7 @@ public void createArticle(Article article) { @Transactional public void updateArticle(int id, Article article) { - Article existingArticle = getArticleById(id); + getArticleById(id); //없으면 예외처리 if (article.getBoardId() != 0) { // boardId가 업데이트 요청에 포함된 경우에만 확인 try { boardDao.findNameById(article.getBoardId()); From a597233aa6f6961a6092122b59e7f99fae0e2fdf Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Sat, 31 May 2025 22:18:33 +0900 Subject: [PATCH 14/22] =?UTF-8?q?Member=EA=B4=80=EB=A0=A8=20JPA=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/bcsd/daos/MemberDAO.java | 64 +++++++------------ .../java/com/example/bcsd/models/Article.java | 3 + .../java/com/example/bcsd/models/Board.java | 3 + .../java/com/example/bcsd/models/Member.java | 5 ++ .../example/bcsd/services/MemberService.java | 6 +- 5 files changed, 36 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/example/bcsd/daos/MemberDAO.java b/src/main/java/com/example/bcsd/daos/MemberDAO.java index cef78148..97606caa 100644 --- a/src/main/java/com/example/bcsd/daos/MemberDAO.java +++ b/src/main/java/com/example/bcsd/daos/MemberDAO.java @@ -1,10 +1,8 @@ package com.example.bcsd.daos; import com.example.bcsd.models.Member; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import org.springframework.stereotype.Repository; import java.util.List; @@ -13,55 +11,39 @@ @Repository public class MemberDAO { - private final JdbcTemplate jdbcTemplate; + @PersistenceContext + private EntityManager em; - @Autowired - public MemberDAO(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - private RowMapper memberRowMapper() { - return (rs, rowNum) -> { - Member dto = new Member(); - dto.setId(rs.getInt("id")); - dto.setEmail(rs.getString("email")); - dto.setName(rs.getString("name")); - dto.setPassword(rs.getString("password")); - return dto; - }; - } - - public Member findById(int id) throws EmptyResultDataAccessException { - String sql = "SELECT * FROM Member WHERE id = ?"; - return jdbcTemplate.queryForObject(sql, memberRowMapper(), id); + public Member findById(int id) { + return em.find(Member.class, id); } public List findAll() { - String sql = "SELECT * FROM Member"; - return jdbcTemplate.query(sql, memberRowMapper()); + return em.createQuery("SELECT m FROM Member m", Member.class).getResultList(); } public void insert(Member member) { - String sql = "INSERT INTO Member (name, email, password) VALUES (?, ?, ?)"; - jdbcTemplate.update(sql, member.getName(), member.getEmail(), member.getPassword()); + em.persist(member); } - public void updateMember(Member member) { - String sql = "UPDATE Member SET name = ?, email = ?, password = ? WHERE id = ?"; - jdbcTemplate.update(sql, member.getName(), member.getEmail(), member.getPassword(), member.getId()); + public void update(Member member) { + Member target = em.find(Member.class, member.getId()); + if (target != null) { + target.setName(member.getName()); + target.setEmail(member.getEmail()); + } } - public void deleteMember(int id) { - String sql = "DELETE FROM Member WHERE id = ?"; - jdbcTemplate.update(sql, id); + public void delete(int id) { + Member member = em.find(Member.class, id); + if (member != null) { + em.remove(member); + } } - public Optional findByEmail(String email) { - String sql = "SELECT * FROM Member WHERE email = ?"; - try { - return Optional.ofNullable(jdbcTemplate.queryForObject(sql, memberRowMapper(), email)); - } catch (EmptyResultDataAccessException e) { - return Optional.empty(); - } + List result = em.createQuery("SELECT m FROM Member m WHERE m.email = :email", Member.class) + .setParameter("email", email) + .getResultList(); + return result.stream().findFirst(); } } \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Article.java b/src/main/java/com/example/bcsd/models/Article.java index 35a78831..17a81e70 100644 --- a/src/main/java/com/example/bcsd/models/Article.java +++ b/src/main/java/com/example/bcsd/models/Article.java @@ -1,7 +1,10 @@ package com.example.bcsd.models; +import jakarta.persistence.Entity; + import java.time.LocalDateTime; +@Entity public class Article { private int id; private int authorId; diff --git a/src/main/java/com/example/bcsd/models/Board.java b/src/main/java/com/example/bcsd/models/Board.java index b35b2e17..2d8cbdd9 100644 --- a/src/main/java/com/example/bcsd/models/Board.java +++ b/src/main/java/com/example/bcsd/models/Board.java @@ -1,5 +1,8 @@ package com.example.bcsd.models; +import jakarta.persistence.Entity; + +@Entity public class Board { private int id; diff --git a/src/main/java/com/example/bcsd/models/Member.java b/src/main/java/com/example/bcsd/models/Member.java index 75391feb..0bc5a0d3 100644 --- a/src/main/java/com/example/bcsd/models/Member.java +++ b/src/main/java/com/example/bcsd/models/Member.java @@ -1,7 +1,12 @@ package com.example.bcsd.models; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity public class Member { + @Id private int id; private String name; private String email; diff --git a/src/main/java/com/example/bcsd/services/MemberService.java b/src/main/java/com/example/bcsd/services/MemberService.java index 17a417f7..87691da8 100644 --- a/src/main/java/com/example/bcsd/services/MemberService.java +++ b/src/main/java/com/example/bcsd/services/MemberService.java @@ -2,8 +2,6 @@ import com.example.bcsd.daos.ArticleDAO; import com.example.bcsd.daos.MemberDAO; -// (향후 과제 기능 구현 시 필요) 게시물 존재 여부 확인을 위해 ArticleDAO 또는 관련 서비스 필요 -// import com.example.bcsd.daos.ArticleDAO; import com.example.bcsd.exceptions.DataConflictException; import com.example.bcsd.exceptions.InvalidRequestException; import com.example.bcsd.exceptions.ResourceNotFoundException; @@ -87,7 +85,7 @@ public void updateMember(int id, Member memberUpdateData) { existingMember.setPassword(memberUpdateData.getPassword()); } - memberDao.updateMember(existingMember); + memberDao.update(existingMember); } @Transactional @@ -97,6 +95,6 @@ public void deleteMember(int id) { if (articleDao.countByAuthorId(id) > 0) { throw new InvalidRequestException("ID가 " + id + "인 사용자는 작성한 게시물이 있어 삭제할 수 없습니다."); } - memberDao.deleteMember(id); + memberDao.delete(id); } } \ No newline at end of file From ad2aaa6610e0c5c06d4cee8f41a06a539ff7f89e Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 2 Jun 2025 22:14:07 +0900 Subject: [PATCH 15/22] =?UTF-8?q?9=EC=A3=BC=EC=B0=A8=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bcsd/controllers/ArticleController.java | 1 + .../bcsd/controllers/MemberController.java | 15 ++--- .../bcsd/controllers/PostController.java | 12 ++-- .../com/example/bcsd/daos/ArticleDAO.java | 61 ++++++++----------- .../java/com/example/bcsd/daos/BoardDAO.java | 18 +++--- .../example/bcsd/services/PostService.java | 55 +++++++---------- 6 files changed, 69 insertions(+), 93 deletions(-) diff --git a/src/main/java/com/example/bcsd/controllers/ArticleController.java b/src/main/java/com/example/bcsd/controllers/ArticleController.java index c2f476e4..808d6424 100644 --- a/src/main/java/com/example/bcsd/controllers/ArticleController.java +++ b/src/main/java/com/example/bcsd/controllers/ArticleController.java @@ -11,6 +11,7 @@ @RestController @RequestMapping("/articles") public class ArticleController { + private final PostService postService; public ArticleController(PostService postService) { diff --git a/src/main/java/com/example/bcsd/controllers/MemberController.java b/src/main/java/com/example/bcsd/controllers/MemberController.java index 85cf68bf..187a3736 100644 --- a/src/main/java/com/example/bcsd/controllers/MemberController.java +++ b/src/main/java/com/example/bcsd/controllers/MemberController.java @@ -22,23 +22,18 @@ public MemberController(MemberService memberService) { @PostMapping public ResponseEntity createMember(@RequestBody Member member) { - Member createdMember = memberService.createMember(member); - // 생성된 리소스의 URI를 반환하는 것이 RESTful API 디자인에 더 적합할 수 있으나, - // 여기서는 생성된 객체와 함께 201 CREATED를 반환합니다. - // 또는 ResponseEntity와 함께 Location 헤더를 사용할 수 있습니다. - return ResponseEntity.status(HttpStatus.CREATED).body(createdMember); + Member created = memberService.createMember(member); + return ResponseEntity.status(HttpStatus.CREATED).body(created); } @GetMapping("/{id}") public ResponseEntity getMemberById(@PathVariable int id) { - Member member = memberService.getMemberById(id); - return ResponseEntity.ok(member); + return ResponseEntity.ok(memberService.getMemberById(id)); } @GetMapping public ResponseEntity> getAllMembers() { - List members = memberService.getAllMembers(); - return ResponseEntity.ok(members); + return ResponseEntity.ok(memberService.getAllMembers()); } @PutMapping("/{id}") @@ -52,4 +47,4 @@ public ResponseEntity deleteMember(@PathVariable int id) { memberService.deleteMember(id); return ResponseEntity.noContent().build(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/example/bcsd/controllers/PostController.java b/src/main/java/com/example/bcsd/controllers/PostController.java index 4db11e40..3fb4f76a 100644 --- a/src/main/java/com/example/bcsd/controllers/PostController.java +++ b/src/main/java/com/example/bcsd/controllers/PostController.java @@ -1,14 +1,12 @@ package com.example.bcsd.controllers; -import com.example.bcsd.models.Article; import com.example.bcsd.services.PostService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; -import java.util.List; + @Controller public class PostController { @@ -20,11 +18,9 @@ public PostController(PostService postService) { @GetMapping("/posts") public String getPosts(@RequestParam int boardId, Model model) { - List
articles = postService.getArticlesByBoard(boardId); - String boardName = postService.getBoardName(boardId); - - model.addAttribute("boardName", boardName); - model.addAttribute("articles", articles); + model.addAttribute("boardName", postService.getBoardName(boardId)); + model.addAttribute("articles", postService.getArticlesByBoard(boardId)); return "posts"; } } + diff --git a/src/main/java/com/example/bcsd/daos/ArticleDAO.java b/src/main/java/com/example/bcsd/daos/ArticleDAO.java index 42315d97..be3a0b4d 100644 --- a/src/main/java/com/example/bcsd/daos/ArticleDAO.java +++ b/src/main/java/com/example/bcsd/daos/ArticleDAO.java @@ -1,62 +1,53 @@ package com.example.bcsd.daos; import com.example.bcsd.models.Article; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import java.util.List; @Repository public class ArticleDAO { - private final JdbcTemplate jdbcTemplate; - public ArticleDAO(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } + @PersistenceContext + private EntityManager em; - public List
findByBoardId(int boardId) { - String sql = "SELECT * FROM article WHERE board_id = ?"; - return jdbcTemplate.query(sql, articleRowMapper(), boardId); + public Article findById(int id) { + return em.find(Article.class, id); } - public Article findById(int id) { - String sql = "SELECT * FROM article WHERE id = ?"; - return jdbcTemplate.queryForObject(sql, articleRowMapper(), id); + public List
findByBoardId(int boardId) { + return em.createQuery("SELECT a FROM Article a WHERE a.boardId = :boardId", Article.class) + .setParameter("boardId", boardId) + .getResultList(); } public void insert(Article article) { - String sql = "INSERT INTO article (author_id, board_id, title, content) VALUES (?, ?, ?, ?)"; - jdbcTemplate.update(sql, article.getAuthorId(), article.getBoardId(), article.getTitle(), article.getContent()); + em.persist(article); } public void update(int id, Article article) { - String sql = "UPDATE article SET board_id = ?, title = ?, content = ?, modified_date = NOW() WHERE id = ?"; - jdbcTemplate.update(sql, article.getBoardId(), article.getTitle(), article.getContent(), id); + Article target = em.find(Article.class, id); + if (target != null) { + target.setBoardId(article.getBoardId()); + target.setTitle(article.getTitle()); + target.setContent(article.getContent()); + target.setUpdatedAt(java.time.LocalDateTime.now()); + } } public void delete(int id) { - String sql = "DELETE FROM article WHERE id = ?"; - jdbcTemplate.update(sql, id); + Article article = em.find(Article.class, id); + if (article != null) { + em.remove(article); + } } public int countByAuthorId(int authorId) { - String sql = "SELECT COUNT(*) FROM article WHERE author_id = ?"; - Integer count = jdbcTemplate.queryForObject(sql, Integer.class, authorId); - return (count != null) ? count : 0; - } - - private RowMapper
articleRowMapper() { - return (rs, rowNum) -> { - Article dto = new Article(); - dto.setId(rs.getInt("id")); - dto.setAuthorId(rs.getInt("author_id")); - dto.setBoardId(rs.getInt("board_id")); - dto.setTitle(rs.getString("title")); - dto.setContent(rs.getString("content")); - dto.setCreatedAt(rs.getTimestamp("created_date").toLocalDateTime()); - dto.setUpdatedAt(rs.getTimestamp("modified_date").toLocalDateTime()); - return dto; - }; + Long count = em.createQuery("SELECT COUNT(a) FROM Article a WHERE a.authorId = :authorId", Long.class) + .setParameter("authorId", authorId) + .getSingleResult(); + return count.intValue(); } } diff --git a/src/main/java/com/example/bcsd/daos/BoardDAO.java b/src/main/java/com/example/bcsd/daos/BoardDAO.java index 8769a30c..3429b291 100644 --- a/src/main/java/com/example/bcsd/daos/BoardDAO.java +++ b/src/main/java/com/example/bcsd/daos/BoardDAO.java @@ -2,23 +2,27 @@ import com.example.bcsd.models.Board; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; + @Repository public class BoardDAO { - private final JdbcTemplate jdbcTemplate; - public BoardDAO(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } + @PersistenceContext + private EntityManager em; - public String findNameById(int id) { - String sql = "SELECT name FROM board WHERE id = ?"; - return jdbcTemplate.queryForObject(sql, String.class, id); + public Optional findNameById(int id) { + List names = em.createQuery("SELECT b.name FROM Board b WHERE b.id = :id", String.class) + .setParameter("id", id) + .getResultList(); + return names.stream().findFirst(); } } diff --git a/src/main/java/com/example/bcsd/services/PostService.java b/src/main/java/com/example/bcsd/services/PostService.java index f799067c..cee15143 100644 --- a/src/main/java/com/example/bcsd/services/PostService.java +++ b/src/main/java/com/example/bcsd/services/PostService.java @@ -6,7 +6,6 @@ import com.example.bcsd.exceptions.InvalidRequestException; import com.example.bcsd.exceptions.ResourceNotFoundException; import com.example.bcsd.models.Article; -import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -26,29 +25,24 @@ public PostService(ArticleDAO articleDao, BoardDAO boardDao, MemberDAO memberDao @Transactional(readOnly = true) public List
getArticlesByBoard(int boardId) { - try { - boardDao.findNameById(boardId); - } catch (EmptyResultDataAccessException e) { - throw new ResourceNotFoundException("ID가 " + boardId + "인 게시판을 찾을 수 없습니다."); - } + boardDao.findNameById(boardId) + .orElseThrow(() -> new ResourceNotFoundException("ID가 " + boardId + "인 게시판을 찾을 수 없습니다.")); return articleDao.findByBoardId(boardId); } @Transactional(readOnly = true) public String getBoardName(int boardId) { - try { - return boardDao.findNameById(boardId); - } catch (EmptyResultDataAccessException e) { - throw new ResourceNotFoundException("ID가 " + boardId + "인 게시판을 찾을 수 없습니다."); - } + return boardDao.findNameById(boardId) + .orElseThrow(() -> new ResourceNotFoundException("ID가 " + boardId + "인 게시판을 찾을 수 없습니다.")); } + @Transactional(readOnly = true) public Article getArticleById(int id) { - try { - return articleDao.findById(id); - } catch (EmptyResultDataAccessException e) { + Article article = articleDao.findById(id); + if (article == null) { throw new ResourceNotFoundException("ID가 " + id + "인 게시물을 찾을 수 없습니다."); } + return article; } @Transactional @@ -59,44 +53,39 @@ public void createArticle(Article article) { throw new InvalidRequestException("게시물 생성 요청 시 필수 값이 누락되었습니다. (authorId, boardId, title, content)"); } - try { //멤버가 있는지 없는지 검사함. 아직 작성 - memberDao.findById(article.getAuthorId()); - } catch (EmptyResultDataAccessException e) { - throw new InvalidRequestException("ID가 " + article.getAuthorId() + "인 사용자를 찾을 수 없습니다."); - } - - try { - boardDao.findNameById(article.getBoardId()); - } catch (EmptyResultDataAccessException e) { - throw new InvalidRequestException("ID가 " + article.getBoardId() + "인 게시판을 찾을 수 없습니다."); + if (memberDao.findById(article.getAuthorId()) == null) { + throw new InvalidRequestException("ID가 " + article.getAuthorId() + "인 사용자를 찾을 수 없습니다."); } + boardDao.findNameById(article.getBoardId()) + .orElseThrow(() -> new InvalidRequestException("ID가 " + article.getBoardId() + "인 게시판을 찾을 수 없습니다.")); + articleDao.insert(article); } @Transactional public void updateArticle(int id, Article article) { - getArticleById(id); //없으면 예외처리 - if (article.getBoardId() != 0) { // boardId가 업데이트 요청에 포함된 경우에만 확인 - try { - boardDao.findNameById(article.getBoardId()); - } catch (EmptyResultDataAccessException e) { - throw new InvalidRequestException("ID가 " + article.getBoardId() + "인 게시판을 찾을 수 없습니다."); - } + getArticleById(id); // 존재 확인 + + if (article.getBoardId() != 0) { + boardDao.findNameById(article.getBoardId()) + .orElseThrow(() -> new InvalidRequestException("ID가 " + article.getBoardId() + "인 게시판을 찾을 수 없습니다.")); } + if (article.getTitle() != null && article.getTitle().isBlank()) { throw new InvalidRequestException("게시물 제목은 비워둘 수 없습니다."); } + if (article.getContent() != null && article.getContent().isBlank()) { throw new InvalidRequestException("게시물 내용은 비워둘 수 없습니다."); } + articleDao.update(id, article); } @Transactional public void deleteArticle(int id) { - getArticleById(id); //없으면 예외발생 + getArticleById(id); // 존재 확인 articleDao.delete(id); } - } From b6e4d9d682f9c4480fd4c478316896a37e514ea1 Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 23 Jun 2025 15:59:12 +0900 Subject: [PATCH 16/22] =?UTF-8?q?Member=20=EC=97=B0=EA=B4=80=EA=B4=80?= =?UTF-8?q?=EA=B3=84=20=EB=A7=A4=ED=95=91=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/bcsd/models/Member.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/bcsd/models/Member.java b/src/main/java/com/example/bcsd/models/Member.java index 0bc5a0d3..4a4f3482 100644 --- a/src/main/java/com/example/bcsd/models/Member.java +++ b/src/main/java/com/example/bcsd/models/Member.java @@ -1,17 +1,23 @@ package com.example.bcsd.models; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; +import jakarta.persistence.*; + +import java.util.ArrayList; +import java.util.List; @Entity public class Member { @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; private String email; private String password; + @OneToMany(mappedBy = "author", fetch = FetchType.LAZY) + private List
articles = new ArrayList<>(); + public Member(int id, String name, String email, String password) { this.id = id; this.name = name; @@ -55,5 +61,13 @@ public void setPassword(String password) { this.password = password; } + public List
getArticles() { + return articles; + } + + public void setArticles(List
articles) { + this.articles = articles; + } + } \ No newline at end of file From 55af08c7a4222cc1f9bcd1d7e769e310449b7897 Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 23 Jun 2025 16:03:07 +0900 Subject: [PATCH 17/22] =?UTF-8?q?Board=20=EC=97=B0=EA=B4=80=EA=B4=80?= =?UTF-8?q?=EA=B3=84=20=EB=A7=A4=ED=95=91=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/bcsd/models/Board.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/bcsd/models/Board.java b/src/main/java/com/example/bcsd/models/Board.java index 2d8cbdd9..bcf0bc70 100644 --- a/src/main/java/com/example/bcsd/models/Board.java +++ b/src/main/java/com/example/bcsd/models/Board.java @@ -1,12 +1,20 @@ package com.example.bcsd.models; -import jakarta.persistence.Entity; +import jakarta.persistence.*; +import java.util.ArrayList; +import java.util.List; @Entity + public class Board { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; + + @OneToMany(mappedBy = "board", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + private List
articles = new ArrayList<>(); public Board() { } @@ -31,4 +39,12 @@ public String getName() { public void setName(String name) { this.name = name; } + + public List
getArticles() { + return articles; + } + + public void setArticles(List
articles) { + this.articles = articles; + } } \ No newline at end of file From 773ebe99df9b24920d0fa8a53b22f7581768312b Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 23 Jun 2025 16:39:36 +0900 Subject: [PATCH 18/22] =?UTF-8?q?dao=EB=A5=BC=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=ED=95=98=EA=B3=A0=20respository=EB=A1=9C=20=EB=8C=80=EC=B2=B4,?= =?UTF-8?q?=20memberService=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/bcsd/models/Article.java | 57 +++++++------------ .../bcsd/repositories/ArticleRepository.java | 15 +++++ .../bcsd/repositories/BoardRepository.java | 9 +++ .../bcsd/repositories/MemberRepository.java | 12 ++++ .../example/bcsd/services/MemberService.java | 39 ++++++------- 5 files changed, 74 insertions(+), 58 deletions(-) create mode 100644 src/main/java/com/example/bcsd/repositories/ArticleRepository.java create mode 100644 src/main/java/com/example/bcsd/repositories/BoardRepository.java create mode 100644 src/main/java/com/example/bcsd/repositories/MemberRepository.java diff --git a/src/main/java/com/example/bcsd/models/Article.java b/src/main/java/com/example/bcsd/models/Article.java index 17a81e70..ef31f43f 100644 --- a/src/main/java/com/example/bcsd/models/Article.java +++ b/src/main/java/com/example/bcsd/models/Article.java @@ -1,14 +1,23 @@ package com.example.bcsd.models; -import jakarta.persistence.Entity; - +import jakarta.persistence.*; import java.time.LocalDateTime; @Entity public class Article { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; - private int authorId; - private int boardId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "author_id") + private Member author; + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "board_id") + private Board board; + private String title; private String content; private LocalDateTime createdAt; @@ -19,50 +28,28 @@ public Article() { this.updatedAt = LocalDateTime.now(); } - public Article(Integer authorId, Integer boardId, String title, String content) { - this.authorId = authorId; - this.boardId = boardId; - this.title = title; - this.content = content; - this.createdAt = LocalDateTime.now(); - this.updatedAt = LocalDateTime.now(); - } - - public Article(Integer id, Integer authorId, Integer boardId, String title, String content, LocalDateTime createdAt, LocalDateTime updatedAt) { - this.id = id; - this.authorId = authorId; - this.boardId = boardId; - this.title = title; - this.content = content; - this.createdAt = createdAt; - this.updatedAt = updatedAt; - } - - public Article(int id, String title) { - } - public int getId() { return id; } - public void setId(Integer id) { + public void setId(int id) { this.id = id; } - public int getAuthorId() { - return authorId; + public Member getAuthor() { + return author; } - public void setAuthorId(int authorId) { - this.authorId = authorId; + public void setAuthor(Member author) { + this.author = author; } - public int getBoardId() { - return boardId; + public Board getBoard() { + return board; } - public void setBoardId(int boardId) { - this.boardId = boardId; + public void setBoard(Board board) { + this.board = board; } public String getTitle() { diff --git a/src/main/java/com/example/bcsd/repositories/ArticleRepository.java b/src/main/java/com/example/bcsd/repositories/ArticleRepository.java new file mode 100644 index 00000000..a7b78417 --- /dev/null +++ b/src/main/java/com/example/bcsd/repositories/ArticleRepository.java @@ -0,0 +1,15 @@ +package com.example.bcsd.repositories; + +import com.example.bcsd.models.Article; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ArticleRepository extends JpaRepository { + + List
findByBoardId(int boardId); + + long countByAuthorId(int authorId); +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/repositories/BoardRepository.java b/src/main/java/com/example/bcsd/repositories/BoardRepository.java new file mode 100644 index 00000000..660637c3 --- /dev/null +++ b/src/main/java/com/example/bcsd/repositories/BoardRepository.java @@ -0,0 +1,9 @@ +package com.example.bcsd.repositories; + +import com.example.bcsd.models.Board; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface BoardRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/repositories/MemberRepository.java b/src/main/java/com/example/bcsd/repositories/MemberRepository.java new file mode 100644 index 00000000..bd538c3e --- /dev/null +++ b/src/main/java/com/example/bcsd/repositories/MemberRepository.java @@ -0,0 +1,12 @@ +package com.example.bcsd.repositories; + +import com.example.bcsd.models.Member; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface MemberRepository extends JpaRepository { + Optional findByEmail(String email); +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/services/MemberService.java b/src/main/java/com/example/bcsd/services/MemberService.java index 87691da8..33ba8db3 100644 --- a/src/main/java/com/example/bcsd/services/MemberService.java +++ b/src/main/java/com/example/bcsd/services/MemberService.java @@ -1,13 +1,12 @@ package com.example.bcsd.services; -import com.example.bcsd.daos.ArticleDAO; -import com.example.bcsd.daos.MemberDAO; import com.example.bcsd.exceptions.DataConflictException; import com.example.bcsd.exceptions.InvalidRequestException; import com.example.bcsd.exceptions.ResourceNotFoundException; import com.example.bcsd.models.Member; +import com.example.bcsd.repositories.ArticleRepository; +import com.example.bcsd.repositories.MemberRepository; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -17,13 +16,13 @@ @Service public class MemberService { - private final MemberDAO memberDao; - private final ArticleDAO articleDao; + private final MemberRepository memberRepository; + private final ArticleRepository articleRepository; @Autowired - public MemberService(MemberDAO memberDao, ArticleDAO articleDao) { - this.memberDao = memberDao; - this.articleDao = articleDao; + public MemberService(MemberRepository memberRepository, ArticleRepository articleRepository) { + this.memberRepository = memberRepository; + this.articleRepository = articleRepository; } @Transactional @@ -34,31 +33,27 @@ public Member createMember(Member member) { throw new InvalidRequestException("사용자 생성 요청 시 필수 값이 누락되었습니다. (name, email, password)"); } - memberDao.findByEmail(member.getEmail()).ifPresent(m -> { + memberRepository.findByEmail(member.getEmail()).ifPresent(m -> { throw new DataConflictException("이미 사용 중인 이메일입니다: " + member.getEmail()); }); - memberDao.insert(member); - return member; + return memberRepository.save(member); } @Transactional(readOnly = true) public Member getMemberById(int id) { - try { - return memberDao.findById(id); - } catch (EmptyResultDataAccessException e) { - throw new ResourceNotFoundException("ID가 " + id + "인 사용자를 찾을 수 없습니다."); - } + return memberRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("ID가 " + id + "인 사용자를 찾을 수 없습니다.")); } @Transactional(readOnly = true) public List getAllMembers() { - return memberDao.findAll(); + return memberRepository.findAll(); } @Transactional public void updateMember(int id, Member memberUpdateData) { - Member existingMember = getMemberById(id); // 존재하지 않으면 예외 + Member existingMember = getMemberById(id); if (memberUpdateData.getName() != null && memberUpdateData.getName().isBlank()) { throw new InvalidRequestException("사용자 이름은 비워둘 수 없습니다."); @@ -71,7 +66,7 @@ public void updateMember(int id, Member memberUpdateData) { } if (memberUpdateData.getEmail() != null && !memberUpdateData.getEmail().equalsIgnoreCase(existingMember.getEmail())) { - Optional memberWithNewEmail = memberDao.findByEmail(memberUpdateData.getEmail()); + Optional memberWithNewEmail = memberRepository.findByEmail(memberUpdateData.getEmail()); if (memberWithNewEmail.isPresent() && memberWithNewEmail.get().getId() != id) { throw new DataConflictException("이미 다른 사용자가 사용 중인 이메일입니다: " + memberUpdateData.getEmail()); } @@ -84,17 +79,15 @@ public void updateMember(int id, Member memberUpdateData) { if (memberUpdateData.getPassword() != null && !memberUpdateData.getPassword().isBlank()) { existingMember.setPassword(memberUpdateData.getPassword()); } - - memberDao.update(existingMember); } @Transactional public void deleteMember(int id) { getMemberById(id); - if (articleDao.countByAuthorId(id) > 0) { + if (articleRepository.countByAuthorId(id) > 0) { throw new InvalidRequestException("ID가 " + id + "인 사용자는 작성한 게시물이 있어 삭제할 수 없습니다."); } - memberDao.delete(id); + memberRepository.deleteById(id); } } \ No newline at end of file From 92d02f2e1da90c2ff1e239169aadd6a54b871716 Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 23 Jun 2025 16:48:33 +0900 Subject: [PATCH 19/22] =?UTF-8?q?PostService=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/bcsd/daos/ArticleDAO.java | 3 +- .../java/com/example/bcsd/daos/BoardDAO.java | 2 + .../java/com/example/bcsd/daos/MemberDAO.java | 4 +- .../java/com/example/bcsd/models/Board.java | 11 +++ .../example/bcsd/services/PostService.java | 96 ++++++++++--------- 5 files changed, 71 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/example/bcsd/daos/ArticleDAO.java b/src/main/java/com/example/bcsd/daos/ArticleDAO.java index be3a0b4d..0099c200 100644 --- a/src/main/java/com/example/bcsd/daos/ArticleDAO.java +++ b/src/main/java/com/example/bcsd/daos/ArticleDAO.java @@ -1,4 +1,4 @@ -package com.example.bcsd.daos; +/*package com.example.bcsd.daos; import com.example.bcsd.models.Article; import org.springframework.stereotype.Repository; @@ -51,3 +51,4 @@ public int countByAuthorId(int authorId) { return count.intValue(); } } +*/ diff --git a/src/main/java/com/example/bcsd/daos/BoardDAO.java b/src/main/java/com/example/bcsd/daos/BoardDAO.java index 3429b291..a3e6417d 100644 --- a/src/main/java/com/example/bcsd/daos/BoardDAO.java +++ b/src/main/java/com/example/bcsd/daos/BoardDAO.java @@ -1,3 +1,4 @@ +/* package com.example.bcsd.daos; @@ -26,3 +27,4 @@ public Optional findNameById(int id) { return names.stream().findFirst(); } } +*/ diff --git a/src/main/java/com/example/bcsd/daos/MemberDAO.java b/src/main/java/com/example/bcsd/daos/MemberDAO.java index 97606caa..87746fe5 100644 --- a/src/main/java/com/example/bcsd/daos/MemberDAO.java +++ b/src/main/java/com/example/bcsd/daos/MemberDAO.java @@ -1,3 +1,4 @@ +/* package com.example.bcsd.daos; import com.example.bcsd.models.Member; @@ -46,4 +47,5 @@ public Optional findByEmail(String email) { .getResultList(); return result.stream().findFirst(); } -} \ No newline at end of file +} + */ \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Board.java b/src/main/java/com/example/bcsd/models/Board.java index bcf0bc70..8bc3738d 100644 --- a/src/main/java/com/example/bcsd/models/Board.java +++ b/src/main/java/com/example/bcsd/models/Board.java @@ -24,6 +24,17 @@ public Board(int id, String name) { this.name = name; } + public void addArticle(Article article) { + articles.add(article); + article.setBoard(this); + } + + public void removeArticle(Article article) { + articles.remove(article); + article.setBoard(null); + } + + public int getId() { return id; } diff --git a/src/main/java/com/example/bcsd/services/PostService.java b/src/main/java/com/example/bcsd/services/PostService.java index cee15143..99e1d0a4 100644 --- a/src/main/java/com/example/bcsd/services/PostService.java +++ b/src/main/java/com/example/bcsd/services/PostService.java @@ -1,11 +1,13 @@ package com.example.bcsd.services; -import com.example.bcsd.daos.ArticleDAO; -import com.example.bcsd.daos.BoardDAO; -import com.example.bcsd.daos.MemberDAO; import com.example.bcsd.exceptions.InvalidRequestException; import com.example.bcsd.exceptions.ResourceNotFoundException; import com.example.bcsd.models.Article; +import com.example.bcsd.models.Board; +import com.example.bcsd.models.Member; +import com.example.bcsd.repositories.ArticleRepository; +import com.example.bcsd.repositories.BoardRepository; +import com.example.bcsd.repositories.MemberRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -13,79 +15,87 @@ @Service public class PostService { - private final ArticleDAO articleDao; - private final BoardDAO boardDao; - private final MemberDAO memberDao; - - public PostService(ArticleDAO articleDao, BoardDAO boardDao, MemberDAO memberDao) { - this.articleDao = articleDao; - this.boardDao = boardDao; - this.memberDao = memberDao; + private final ArticleRepository articleRepository; + private final BoardRepository boardRepository; + private final MemberRepository memberRepository; + + public PostService(ArticleRepository articleRepository, BoardRepository boardRepository, MemberRepository memberRepository) { + this.articleRepository = articleRepository; + this.boardRepository = boardRepository; + this.memberRepository = memberRepository; } @Transactional(readOnly = true) public List
getArticlesByBoard(int boardId) { - boardDao.findNameById(boardId) - .orElseThrow(() -> new ResourceNotFoundException("ID가 " + boardId + "인 게시판을 찾을 수 없습니다.")); - return articleDao.findByBoardId(boardId); + if (!boardRepository.existsById(boardId)) { + throw new ResourceNotFoundException("ID가 " + boardId + "인 게시판을 찾을 수 없습니다."); + } + return articleRepository.findByBoardId(boardId); } @Transactional(readOnly = true) public String getBoardName(int boardId) { - return boardDao.findNameById(boardId) + return boardRepository.findById(boardId) + .map(Board::getName) .orElseThrow(() -> new ResourceNotFoundException("ID가 " + boardId + "인 게시판을 찾을 수 없습니다.")); } @Transactional(readOnly = true) public Article getArticleById(int id) { - Article article = articleDao.findById(id); - if (article == null) { - throw new ResourceNotFoundException("ID가 " + id + "인 게시물을 찾을 수 없습니다."); - } + Article article = articleRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("ID가 " + id + "인 게시물을 찾을 수 없습니다.")); return article; } @Transactional public void createArticle(Article article) { - if (article.getAuthorId() == 0 || article.getBoardId() == 0 || + if (article.getAuthor() == null || article.getAuthor().getId() == 0 || + article.getBoard() == null || article.getBoard().getId() == 0 || article.getTitle() == null || article.getTitle().isBlank() || article.getContent() == null || article.getContent().isBlank()) { throw new InvalidRequestException("게시물 생성 요청 시 필수 값이 누락되었습니다. (authorId, boardId, title, content)"); } - if (memberDao.findById(article.getAuthorId()) == null) { - throw new InvalidRequestException("ID가 " + article.getAuthorId() + "인 사용자를 찾을 수 없습니다."); - } + Member author = memberRepository.findById(article.getAuthor().getId()) + .orElseThrow(() -> new InvalidRequestException("ID가 " + article.getAuthor().getId() + "인 사용자를 찾을 수 없습니다.")); + + Board board = boardRepository.findById(article.getBoard().getId()) + .orElseThrow(() -> new InvalidRequestException("ID가 " + article.getBoard().getId() + "인 게시판을 찾을 수 없습니다.")); - boardDao.findNameById(article.getBoardId()) - .orElseThrow(() -> new InvalidRequestException("ID가 " + article.getBoardId() + "인 게시판을 찾을 수 없습니다.")); + article.setAuthor(author); - articleDao.insert(article); + board.addArticle(article); + boardRepository.save(board); } @Transactional - public void updateArticle(int id, Article article) { - getArticleById(id); // 존재 확인 - - if (article.getBoardId() != 0) { - boardDao.findNameById(article.getBoardId()) - .orElseThrow(() -> new InvalidRequestException("ID가 " + article.getBoardId() + "인 게시판을 찾을 수 없습니다.")); - } - - if (article.getTitle() != null && article.getTitle().isBlank()) { - throw new InvalidRequestException("게시물 제목은 비워둘 수 없습니다."); + public void updateArticle(int id, Article articleUpdateData) { + Article existingArticle = getArticleById(id); + + if (articleUpdateData.getTitle() != null) { + if (articleUpdateData.getTitle().isBlank()) { + throw new InvalidRequestException("게시물 제목은 비워둘 수 없습니다."); + } + existingArticle.setTitle(articleUpdateData.getTitle()); } - if (article.getContent() != null && article.getContent().isBlank()) { - throw new InvalidRequestException("게시물 내용은 비워둘 수 없습니다."); + if (articleUpdateData.getContent() != null) { + if (articleUpdateData.getContent().isBlank()) { + throw new InvalidRequestException("게시물 내용은 비워둘 수 없습니다."); + } + existingArticle.setContent(articleUpdateData.getContent()); } - - articleDao.update(id, article); + existingArticle.setUpdatedAt(java.time.LocalDateTime.now()); } @Transactional public void deleteArticle(int id) { - getArticleById(id); // 존재 확인 - articleDao.delete(id); + Article article = getArticleById(id); + Board board = article.getBoard(); + if (board != null) { + board.getArticles().remove(article); + } else { + articleRepository.delete(article); + } } -} +} \ No newline at end of file From 172272121aa6d2ccc36fd47b6418ae9e3706541c Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 30 Jun 2025 13:28:07 +0900 Subject: [PATCH 20/22] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8,=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=EA=B0=80=EC=9E=85=20html=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 +++++ src/main/resources/templates/login.html | 21 +++++++++++++++++++++ src/main/resources/templates/signup.html | 24 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 src/main/resources/templates/login.html create mode 100644 src/main/resources/templates/signup.html diff --git a/build.gradle b/build.gradle index 72214f03..4564b78b 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,11 @@ dependencies { runtimeOnly 'com.mysql:mysql-connector-j' testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' + } tasks.named('test') { diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html new file mode 100644 index 00000000..67ba52a6 --- /dev/null +++ b/src/main/resources/templates/login.html @@ -0,0 +1,21 @@ + + + + + Login Form + + +

Login Form

+
+ +

+ + +

+ + +
+ +

Don't have an account? Sign up here

+ + diff --git a/src/main/resources/templates/signup.html b/src/main/resources/templates/signup.html new file mode 100644 index 00000000..e58f1a0a --- /dev/null +++ b/src/main/resources/templates/signup.html @@ -0,0 +1,24 @@ + + + + + Signup Form + + +

Signup Form

+
+ +

+ + +

+ + +

+ + +
+ +

Already have an account? Log in here

+ + From c2fce431b04f29d72f56ae30f4f432b700099bdb Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 30 Jun 2025 13:42:04 +0900 Subject: [PATCH 21/22] =?UTF-8?q?session=20=EC=9D=B8=EC=A6=9D=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=20=EC=82=AC=EC=9A=A9=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?DTO=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 ++--- src/main/java/com/example/bcsd/dtos/LoginDto.java | 11 +++++++++++ src/main/java/com/example/bcsd/dtos/SignupDto.java | 11 +++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/example/bcsd/dtos/LoginDto.java create mode 100644 src/main/java/com/example/bcsd/dtos/SignupDto.java diff --git a/build.gradle b/build.gradle index 4564b78b..013d8a35 100644 --- a/build.gradle +++ b/build.gradle @@ -28,9 +28,8 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'io.jsonwebtoken:jjwt-api:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' + compileOnly 'org.projectlombok:lombok:1.18.32' + annotationProcessor 'org.projectlombok:lombok:1.18.32' } diff --git a/src/main/java/com/example/bcsd/dtos/LoginDto.java b/src/main/java/com/example/bcsd/dtos/LoginDto.java new file mode 100644 index 00000000..e2befea4 --- /dev/null +++ b/src/main/java/com/example/bcsd/dtos/LoginDto.java @@ -0,0 +1,11 @@ +package com.example.bcsd.dtos; + +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +public class LoginDto { + private String account; + private String password; + private String confirmPassword; +} \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/dtos/SignupDto.java b/src/main/java/com/example/bcsd/dtos/SignupDto.java new file mode 100644 index 00000000..2456a53d --- /dev/null +++ b/src/main/java/com/example/bcsd/dtos/SignupDto.java @@ -0,0 +1,11 @@ +package com.example.bcsd.dtos; + +import lombok.Getter; +import lombok.Setter; + +@Getter @Setter +public class SignupDto { + private String account; + private String password; + private String confirmPassword; +} \ No newline at end of file From 54845410e7201635e81a0736a299e7dc3a768cdb Mon Sep 17 00:00:00 2001 From: hyunseong0307 Date: Mon, 30 Jun 2025 14:20:32 +0900 Subject: [PATCH 22/22] =?UTF-8?q?controller=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- .../bcsd/controllers/SessionController.java | 63 +++++++++++++++++++ .../java/com/example/bcsd/dtos/LoginDto.java | 1 - .../java/com/example/bcsd/dtos/SignupDto.java | 2 + .../java/com/example/bcsd/models/Member.java | 12 +++- .../bcsd/repositories/MemberRepository.java | 1 + src/main/resources/templates/signup.html | 20 +++--- 7 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/example/bcsd/controllers/SessionController.java diff --git a/build.gradle b/build.gradle index 013d8a35..05c9215d 100644 --- a/build.gradle +++ b/build.gradle @@ -22,12 +22,12 @@ 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 'org.springframework.boot:spring-boot-starter' runtimeOnly 'com.mysql:mysql-connector-j' testImplementation 'org.springframework.boot:spring-boot-starter-test' - implementation 'org.springframework.boot:spring-boot-starter-security' compileOnly 'org.projectlombok:lombok:1.18.32' annotationProcessor 'org.projectlombok:lombok:1.18.32' diff --git a/src/main/java/com/example/bcsd/controllers/SessionController.java b/src/main/java/com/example/bcsd/controllers/SessionController.java new file mode 100644 index 00000000..9d941c2f --- /dev/null +++ b/src/main/java/com/example/bcsd/controllers/SessionController.java @@ -0,0 +1,63 @@ +package com.example.bcsd.controllers; + +import com.example.bcsd.dtos.LoginDto; +import com.example.bcsd.dtos.SignupDto; +import com.example.bcsd.models.Member; +import com.example.bcsd.repositories.MemberRepository; +import jakarta.servlet.http.HttpSession; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.Optional; + +@Controller +@RequiredArgsConstructor +public class SessionController { + + private final MemberRepository memberRepository; + + @GetMapping("/login") + public String loginForm() { + return "login"; + } + @GetMapping("/signup") + public String signupForm() { + return "signup"; // templates/login.html 파일 필요 + } + + @PostMapping("/signup") + public String signup(SignupDto request) { + if (!request.getPassword().equals(request.getConfirmPassword())) { + return "비밀번호가 일치하지 않습니다."; + } + + if (memberRepository.findByAccount(request.getAccount()).isPresent()) { + return "이미 존재하는 계정입니다."; + } + + Member member = new Member(); + member.setAccount(request.getAccount()); + member.setPassword(request.getPassword()); + member.setEmail(request.getEmail()); + member.setName(request.getName()); + memberRepository.save(member); + + return "redirect:/login"; + } + + @PostMapping("/login") + public String login(LoginDto request, HttpSession session) { + Optional optionalMember = memberRepository.findByAccount(request.getAccount()); + + if (optionalMember.isEmpty()) return "존재하지 않는 계정입니다."; + Member member = optionalMember.get(); + + if (!member.getPassword().equals(request.getPassword())) { + return "비밀번호가 틀렸습니다."; + } + + session.setAttribute("loginMember", member); // 세션 저장 + return "redirect:/"; + } +} diff --git a/src/main/java/com/example/bcsd/dtos/LoginDto.java b/src/main/java/com/example/bcsd/dtos/LoginDto.java index e2befea4..26275b41 100644 --- a/src/main/java/com/example/bcsd/dtos/LoginDto.java +++ b/src/main/java/com/example/bcsd/dtos/LoginDto.java @@ -7,5 +7,4 @@ public class LoginDto { private String account; private String password; - private String confirmPassword; } \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/dtos/SignupDto.java b/src/main/java/com/example/bcsd/dtos/SignupDto.java index 2456a53d..d2035ee2 100644 --- a/src/main/java/com/example/bcsd/dtos/SignupDto.java +++ b/src/main/java/com/example/bcsd/dtos/SignupDto.java @@ -8,4 +8,6 @@ public class SignupDto { private String account; private String password; private String confirmPassword; + private String email; + private String name; } \ No newline at end of file diff --git a/src/main/java/com/example/bcsd/models/Member.java b/src/main/java/com/example/bcsd/models/Member.java index 4a4f3482..481a2431 100644 --- a/src/main/java/com/example/bcsd/models/Member.java +++ b/src/main/java/com/example/bcsd/models/Member.java @@ -11,6 +11,7 @@ public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; + private String account; private String name; private String email; private String password; @@ -18,8 +19,9 @@ public class Member { @OneToMany(mappedBy = "author", fetch = FetchType.LAZY) private List
articles = new ArrayList<>(); - public Member(int id, String name, String email, String password) { + public Member(int id, String account, String name, String email, String password) { this.id = id; + this.account = account; this.name = name; this.email = email; this.password = password; @@ -29,6 +31,14 @@ public Member() { } + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + public int getId() { return id; } diff --git a/src/main/java/com/example/bcsd/repositories/MemberRepository.java b/src/main/java/com/example/bcsd/repositories/MemberRepository.java index bd538c3e..cf21287f 100644 --- a/src/main/java/com/example/bcsd/repositories/MemberRepository.java +++ b/src/main/java/com/example/bcsd/repositories/MemberRepository.java @@ -9,4 +9,5 @@ @Repository public interface MemberRepository extends JpaRepository { Optional findByEmail(String email); + Optional findByAccount(String account); } \ No newline at end of file diff --git a/src/main/resources/templates/signup.html b/src/main/resources/templates/signup.html index e58f1a0a..ba538275 100644 --- a/src/main/resources/templates/signup.html +++ b/src/main/resources/templates/signup.html @@ -2,23 +2,29 @@ - Signup Form + 회원가입 -

Signup Form

+

회원가입

- +

- +

- +

- + +

+ + +

+ +
-

Already have an account? Log in here

+

이미 계정이 있으신가요? 로그인