From b459a95ad0871758e0f21d823ca4a7aa796dc2fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A3=BC=EB=B3=91=EC=A3=BC?= Date: Mon, 13 May 2024 01:11:48 +0900 Subject: [PATCH 1/6] all code add --- build.gradle | 4 + src/main/java/roomescape/PreInit.java | 23 +++++ .../roomescape/domain/Dto/RequestDto.java | 24 ++++++ .../roomescape/domain/Dto/ResponseDto.java | 26 ++++++ .../roomescape/domain/Model/Reservation.java | 15 ++++ .../Repository/ReservationRepository.java | 46 ++++++++++ .../domain/exception/NoDataException.java | 7 ++ .../NotFoundReservationException.java | 7 ++ .../ExceptionHandlerData.java | 20 +++++ .../web/Controller/HomeController.java | 16 ++++ .../web/Controller/ReservationController.java | 60 +++++++++++++ src/test/java/roomescape/MissionStepTest.java | 86 ++++++++++++++++++- 12 files changed, 333 insertions(+), 1 deletion(-) create mode 100644 src/main/java/roomescape/PreInit.java create mode 100644 src/main/java/roomescape/domain/Dto/RequestDto.java create mode 100644 src/main/java/roomescape/domain/Dto/ResponseDto.java create mode 100644 src/main/java/roomescape/domain/Model/Reservation.java create mode 100644 src/main/java/roomescape/domain/Repository/ReservationRepository.java create mode 100644 src/main/java/roomescape/domain/exception/NoDataException.java create mode 100644 src/main/java/roomescape/domain/exception/NotFoundReservationException.java create mode 100644 src/main/java/roomescape/domain/exceptionHandler/ExceptionHandlerData.java create mode 100644 src/main/java/roomescape/web/Controller/HomeController.java create mode 100644 src/main/java/roomescape/web/Controller/ReservationController.java diff --git a/build.gradle b/build.gradle index 57267157c..1bd5ad96f 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,10 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'io.rest-assured:rest-assured:5.3.1' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' } test { diff --git a/src/main/java/roomescape/PreInit.java b/src/main/java/roomescape/PreInit.java new file mode 100644 index 000000000..20bc487dd --- /dev/null +++ b/src/main/java/roomescape/PreInit.java @@ -0,0 +1,23 @@ +package roomescape; + +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import roomescape.domain.Dto.RequestDto; +import roomescape.domain.Repository.ReservationRepository; + +@Component +@RequiredArgsConstructor +public class PreInit { + + private final ReservationRepository reservationRepository; +// @PostConstruct +// public void init() { +// RequestDto requestDto1 = new RequestDto(); +// requestDto1.setName("ju"); +// requestDto1.setTime("asdasd"); +// requestDto1.setDate("asdasd"); +// reservationRepository.save(requestDto1.toReservation()); +// +// } +} diff --git a/src/main/java/roomescape/domain/Dto/RequestDto.java b/src/main/java/roomescape/domain/Dto/RequestDto.java new file mode 100644 index 000000000..0890e3e58 --- /dev/null +++ b/src/main/java/roomescape/domain/Dto/RequestDto.java @@ -0,0 +1,24 @@ +package roomescape.domain.Dto; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import roomescape.domain.Model.Reservation; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Getter @Setter +public class RequestDto { + private String name; + private String date; + private String time; + + public Reservation toReservation() { + Reservation reservation = new Reservation(); + reservation.setName(name); + reservation.setDate(date); + reservation.setTime(time); + return reservation; + } +} \ No newline at end of file diff --git a/src/main/java/roomescape/domain/Dto/ResponseDto.java b/src/main/java/roomescape/domain/Dto/ResponseDto.java new file mode 100644 index 000000000..87a8503cd --- /dev/null +++ b/src/main/java/roomescape/domain/Dto/ResponseDto.java @@ -0,0 +1,26 @@ +package roomescape.domain.Dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import roomescape.domain.Model.Reservation; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Data +public class ResponseDto { + private Long id; + private String name; + private String date; + private String time; + + public static ResponseDto makeResponse(Reservation reservation) { + ResponseDto responseDto = new ResponseDto(); + responseDto.id = reservation.getId(); + responseDto.name = reservation.getName(); + responseDto.date = reservation.getDate(); + responseDto.time = reservation.getTime(); + return responseDto; + } + +} \ No newline at end of file diff --git a/src/main/java/roomescape/domain/Model/Reservation.java b/src/main/java/roomescape/domain/Model/Reservation.java new file mode 100644 index 000000000..9fb0cbbc6 --- /dev/null +++ b/src/main/java/roomescape/domain/Model/Reservation.java @@ -0,0 +1,15 @@ +package roomescape.domain.Model; + +import lombok.Data; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Data +public class Reservation { + private Long id; + private String name; + private String date; + private String time; + +} diff --git a/src/main/java/roomescape/domain/Repository/ReservationRepository.java b/src/main/java/roomescape/domain/Repository/ReservationRepository.java new file mode 100644 index 000000000..84834bbd5 --- /dev/null +++ b/src/main/java/roomescape/domain/Repository/ReservationRepository.java @@ -0,0 +1,46 @@ +package roomescape.domain.Repository; + +import org.springframework.stereotype.Repository; +import roomescape.domain.Model.Reservation; +import roomescape.domain.exception.NoDataException; +import roomescape.domain.exception.NotFoundReservationException; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +@Repository +public class ReservationRepository { + private static final HashMap store = new HashMap(); + private static Long sequence = 0L; + + + public Reservation save(Reservation reservation) { + validateReservation(reservation); + reservation.setId(++sequence); + store.put(reservation.getId(),reservation); + return reservation; + } + + private void validateReservation(Reservation reservation) { + if(reservation.getTime().isBlank() || reservation.getDate().isBlank() || reservation.getName().isBlank()) + throw new NoDataException("데이터가 비어있습니다."); + } + + public Reservation findById(Long id) { + return store.get(id); + } + + public List findAll() { + return new ArrayList<>(store.values()); + } + + public Reservation deleteReservation(Long id){ + if (store.containsKey(id)) { + Reservation removeReservation = store.get(id); + store.remove(id); + return removeReservation; + } + throw new NotFoundReservationException("해당 id를 찾지 못하였습니다."); + } +} diff --git a/src/main/java/roomescape/domain/exception/NoDataException.java b/src/main/java/roomescape/domain/exception/NoDataException.java new file mode 100644 index 000000000..39daa82b0 --- /dev/null +++ b/src/main/java/roomescape/domain/exception/NoDataException.java @@ -0,0 +1,7 @@ +package roomescape.domain.exception; + +public class NoDataException extends RuntimeException{ + public NoDataException(String message) { + super(message); + } +} diff --git a/src/main/java/roomescape/domain/exception/NotFoundReservationException.java b/src/main/java/roomescape/domain/exception/NotFoundReservationException.java new file mode 100644 index 000000000..d8516153c --- /dev/null +++ b/src/main/java/roomescape/domain/exception/NotFoundReservationException.java @@ -0,0 +1,7 @@ +package roomescape.domain.exception; + +public class NotFoundReservationException extends RuntimeException{ + public NotFoundReservationException(String message) { + super(message); + } +} diff --git a/src/main/java/roomescape/domain/exceptionHandler/ExceptionHandlerData.java b/src/main/java/roomescape/domain/exceptionHandler/ExceptionHandlerData.java new file mode 100644 index 000000000..4a27bb976 --- /dev/null +++ b/src/main/java/roomescape/domain/exceptionHandler/ExceptionHandlerData.java @@ -0,0 +1,20 @@ +package roomescape.domain.exceptionHandler; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import roomescape.domain.exception.NoDataException; +import roomescape.domain.exception.NotFoundReservationException; + +@ControllerAdvice +public class ExceptionHandlerData { + @ExceptionHandler(NotFoundReservationException.class) + public ResponseEntity handleExceptionNotFound(NotFoundReservationException e) { + return ResponseEntity.badRequest().build(); + } + + @ExceptionHandler(NoDataException.class) + public ResponseEntity handleExceptionNoData(NoDataException e) { + return ResponseEntity.badRequest().build(); + } +} diff --git a/src/main/java/roomescape/web/Controller/HomeController.java b/src/main/java/roomescape/web/Controller/HomeController.java new file mode 100644 index 000000000..bdfdde910 --- /dev/null +++ b/src/main/java/roomescape/web/Controller/HomeController.java @@ -0,0 +1,16 @@ +package roomescape.web.Controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/") +public class HomeController { + + @GetMapping + public String home() { + return "home"; + } + +} diff --git a/src/main/java/roomescape/web/Controller/ReservationController.java b/src/main/java/roomescape/web/Controller/ReservationController.java new file mode 100644 index 000000000..7d3c06765 --- /dev/null +++ b/src/main/java/roomescape/web/Controller/ReservationController.java @@ -0,0 +1,60 @@ +package roomescape.web.Controller; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import org.apache.catalina.connector.Response; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import roomescape.domain.Dto.RequestDto; +import roomescape.domain.Dto.ResponseDto; +import roomescape.domain.Model.Reservation; +import roomescape.domain.Repository.ReservationRepository; + + +import java.lang.reflect.Member; +import java.net.URI; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.toList; + +@Controller +@RequiredArgsConstructor +public class ReservationController { + private final ReservationRepository reservationRepository; + + @GetMapping("/reservation") + public String reservation(){ + return "reservation"; + } + + @GetMapping ("/reservations") + @ResponseBody + public ResponseEntity> checkReservation(){ + List reservations = reservationRepository.findAll(); + List responseDtos = reservations.stream() + .map(ResponseDto::makeResponse) + .toList(); + return ResponseEntity.ok(responseDtos); + } + @PostMapping("/reservations") + @ResponseBody + public ResponseEntity addReservation(@RequestBody RequestDto requestDto){ + + Reservation reservation = reservationRepository.save(requestDto.toReservation()); + ResponseDto responseDto = ResponseDto.makeResponse(reservation); + URI location = URI.create("/reservations/"+responseDto.getId()); + return ResponseEntity.created(location).body(responseDto); + } + + @DeleteMapping("/reservations/{id}") + public ResponseEntity deleteReservation(@PathVariable("id") Long id) { + reservationRepository.deleteReservation(id); + return ResponseEntity.noContent().build(); + } + +} diff --git a/src/test/java/roomescape/MissionStepTest.java b/src/test/java/roomescape/MissionStepTest.java index cf4efbe91..4d7f8ac59 100644 --- a/src/test/java/roomescape/MissionStepTest.java +++ b/src/test/java/roomescape/MissionStepTest.java @@ -1,14 +1,28 @@ package roomescape; import io.restassured.RestAssured; +import io.restassured.http.ContentType; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.annotation.DirtiesContext; +import roomescape.domain.Dto.ResponseDto; +import roomescape.domain.Model.Reservation; + + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.Matchers.is; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) public class MissionStepTest { - @Test void 일단계() { RestAssured.given().log().all() @@ -16,4 +30,74 @@ public class MissionStepTest { .then().log().all() .statusCode(200); } + + @Test + void 이단계() { + RestAssured.given().log().all() + .when().get("/reservation") + .then().log().all() + .statusCode(200); + + RestAssured.given().log().all() + .when().get("/reservations") + .then().log().all() + .statusCode(200) + .body("size()", is(0)); // 아직 생성 요청이 없으니 Controller에서 임의로 넣어준 Reservation 갯수 만큼 검증하거나 0개임을 확인하세요. + } + + @Test + void 삼단계() { + Map params = new HashMap<>(); + params.put("name", "브라운"); + params.put("date", "2023-08-05"); + params.put("time", "15:40"); + + RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(params) + .when().post("/reservations") + .then().log().all() + .statusCode(201) + .header("Location", "/reservations/1") + .body("id", is(1)); + + RestAssured.given().log().all() + .when().get("/reservations") + .then().log().all() + .statusCode(200) + .body("size()", is(1)); + + RestAssured.given().log().all() + .when().delete("/reservations/1") + .then().log().all() + .statusCode(204); + + RestAssured.given().log().all() + .when().get("/reservations") + .then().log().all() + .statusCode(200) + .body("size()", is(0)); + } + + @Test + void 사단계() { + Map params = new HashMap<>(); + params.put("name", "브라운"); + params.put("date", ""); + params.put("time", ""); + + // 필요한 인자가 없는 경우 + RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(params) + .when().post("/reservations") + .then().log().all() + .statusCode(400); + + // 삭제할 예약이 없는 경우 + RestAssured.given().log().all() + .when().delete("/reservations/1") + .then().log().all() + .statusCode(400); + } } From 701e52b375d9a173cc81c73904b9198389b4320d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A3=BC=EB=B3=91=EC=A3=BC?= Date: Mon, 13 May 2024 16:16:04 +0900 Subject: [PATCH 2/6] modified --- .../roomescape/domain/Dto/RequestDto.java | 2 +- .../Repository/ReservationRepository.java | 6 --- .../web/Controller/ReservationController.java | 9 +++-- .../web/Service/ReservationService.java | 39 +++++++++++++++++++ 4 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 src/main/java/roomescape/web/Service/ReservationService.java diff --git a/src/main/java/roomescape/domain/Dto/RequestDto.java b/src/main/java/roomescape/domain/Dto/RequestDto.java index 0890e3e58..acafdad09 100644 --- a/src/main/java/roomescape/domain/Dto/RequestDto.java +++ b/src/main/java/roomescape/domain/Dto/RequestDto.java @@ -8,7 +8,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; -@Getter @Setter +@Data public class RequestDto { private String name; private String date; diff --git a/src/main/java/roomescape/domain/Repository/ReservationRepository.java b/src/main/java/roomescape/domain/Repository/ReservationRepository.java index 84834bbd5..e86811263 100644 --- a/src/main/java/roomescape/domain/Repository/ReservationRepository.java +++ b/src/main/java/roomescape/domain/Repository/ReservationRepository.java @@ -16,17 +16,11 @@ public class ReservationRepository { public Reservation save(Reservation reservation) { - validateReservation(reservation); reservation.setId(++sequence); store.put(reservation.getId(),reservation); return reservation; } - private void validateReservation(Reservation reservation) { - if(reservation.getTime().isBlank() || reservation.getDate().isBlank() || reservation.getName().isBlank()) - throw new NoDataException("데이터가 비어있습니다."); - } - public Reservation findById(Long id) { return store.get(id); } diff --git a/src/main/java/roomescape/web/Controller/ReservationController.java b/src/main/java/roomescape/web/Controller/ReservationController.java index 7d3c06765..d5029a578 100644 --- a/src/main/java/roomescape/web/Controller/ReservationController.java +++ b/src/main/java/roomescape/web/Controller/ReservationController.java @@ -11,6 +11,7 @@ import roomescape.domain.Dto.ResponseDto; import roomescape.domain.Model.Reservation; import roomescape.domain.Repository.ReservationRepository; +import roomescape.web.Service.ReservationService; import java.lang.reflect.Member; @@ -25,7 +26,7 @@ @Controller @RequiredArgsConstructor public class ReservationController { - private final ReservationRepository reservationRepository; + private final ReservationService reservationService; @GetMapping("/reservation") public String reservation(){ @@ -35,7 +36,7 @@ public String reservation(){ @GetMapping ("/reservations") @ResponseBody public ResponseEntity> checkReservation(){ - List reservations = reservationRepository.findAll(); + List reservations = reservationService.findAll(); List responseDtos = reservations.stream() .map(ResponseDto::makeResponse) .toList(); @@ -45,7 +46,7 @@ public ResponseEntity> checkReservation(){ @ResponseBody public ResponseEntity addReservation(@RequestBody RequestDto requestDto){ - Reservation reservation = reservationRepository.save(requestDto.toReservation()); + Reservation reservation = reservationService.join(requestDto.toReservation()); ResponseDto responseDto = ResponseDto.makeResponse(reservation); URI location = URI.create("/reservations/"+responseDto.getId()); return ResponseEntity.created(location).body(responseDto); @@ -53,7 +54,7 @@ public ResponseEntity addReservation(@RequestBody RequestDto reques @DeleteMapping("/reservations/{id}") public ResponseEntity deleteReservation(@PathVariable("id") Long id) { - reservationRepository.deleteReservation(id); + reservationService.delete(id); return ResponseEntity.noContent().build(); } diff --git a/src/main/java/roomescape/web/Service/ReservationService.java b/src/main/java/roomescape/web/Service/ReservationService.java new file mode 100644 index 000000000..1439ec27d --- /dev/null +++ b/src/main/java/roomescape/web/Service/ReservationService.java @@ -0,0 +1,39 @@ +package roomescape.web.Service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import roomescape.domain.Model.Reservation; +import roomescape.domain.Repository.ReservationRepository; +import roomescape.domain.exception.NoDataException; +import roomescape.domain.exception.NotFoundReservationException; + +import java.util.ArrayList; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class ReservationService { + private final ReservationRepository reservationRepository; + + public Reservation join(Reservation reservation) { + validateReservation(reservation); + return reservationRepository.save(reservation); + } + + private void validateReservation(Reservation reservation) { + if(reservation.getTime().isBlank() || reservation.getDate().isBlank() || reservation.getName().isBlank()) + throw new NoDataException("데이터가 비어있습니다."); + } + + public Reservation findById(Long id) { + return reservationRepository.findById(id); + } + + public List findAll() { + return reservationRepository.findAll(); + } + + public Reservation delete(Long id){ + return reservationRepository.deleteReservation(id); + } +} From ea4fa7042d9f91e020230c1569e4d888ac4db556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A3=BC=EB=B3=91=EC=A3=BC?= Date: Wed, 15 May 2024 15:50:04 +0900 Subject: [PATCH 3/6] =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=9B=EC=9D=80=20?= =?UTF-8?q?=EB=82=B4=EC=9A=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roomescape/domain/Repository/ReservationRepository.java | 4 ---- .../java/roomescape/web/Controller/ReservationController.java | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/roomescape/domain/Repository/ReservationRepository.java b/src/main/java/roomescape/domain/Repository/ReservationRepository.java index e86811263..2ec17f109 100644 --- a/src/main/java/roomescape/domain/Repository/ReservationRepository.java +++ b/src/main/java/roomescape/domain/Repository/ReservationRepository.java @@ -21,10 +21,6 @@ public Reservation save(Reservation reservation) { return reservation; } - public Reservation findById(Long id) { - return store.get(id); - } - public List findAll() { return new ArrayList<>(store.values()); } diff --git a/src/main/java/roomescape/web/Controller/ReservationController.java b/src/main/java/roomescape/web/Controller/ReservationController.java index d5029a578..80a38176b 100644 --- a/src/main/java/roomescape/web/Controller/ReservationController.java +++ b/src/main/java/roomescape/web/Controller/ReservationController.java @@ -53,7 +53,7 @@ public ResponseEntity addReservation(@RequestBody RequestDto reques } @DeleteMapping("/reservations/{id}") - public ResponseEntity deleteReservation(@PathVariable("id") Long id) { + public ResponseEntity deleteReservation(@PathVariable Long id) { reservationService.delete(id); return ResponseEntity.noContent().build(); } From e420e01064bab83ee691885ccd00bf9424205e64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A3=BC=EB=B3=91=EC=A3=BC?= Date: Mon, 20 May 2024 13:24:09 +0900 Subject: [PATCH 4/6] =?UTF-8?q?5,6,7=20=EB=8B=A8=EA=B3=84=20=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 + .../roomescape/domain/Dto/RequestDto.java | 11 +-- .../roomescape/domain/Dto/ResponseDto.java | 20 +++-- .../roomescape/domain/Model/Reservation.java | 15 +++- .../domain/Repository/BasicRepository.java | 14 ++++ .../Repository/JdbcReservationRepository.java | 56 +++++++++++++ .../web/Controller/ReservationController.java | 17 ++-- .../web/Service/ReservationService.java | 39 --------- src/main/resources/application.properties | 3 + src/main/resources/schema.sql | 8 ++ src/test/java/roomescape/JdbcTest.java | 82 +++++++++++++++++++ 11 files changed, 208 insertions(+), 59 deletions(-) create mode 100644 src/main/java/roomescape/domain/Repository/BasicRepository.java create mode 100644 src/main/java/roomescape/domain/Repository/JdbcReservationRepository.java delete mode 100644 src/main/java/roomescape/web/Service/ReservationService.java create mode 100644 src/main/resources/schema.sql create mode 100644 src/test/java/roomescape/JdbcTest.java diff --git a/build.gradle b/build.gradle index 1bd5ad96f..d2b20c563 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,9 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter' + runtimeOnly 'com.h2database:h2' testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'org.springframework.boot:spring-boot-starter-jdbc' testImplementation 'io.rest-assured:rest-assured:5.3.1' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' diff --git a/src/main/java/roomescape/domain/Dto/RequestDto.java b/src/main/java/roomescape/domain/Dto/RequestDto.java index acafdad09..6ea1bcdd1 100644 --- a/src/main/java/roomescape/domain/Dto/RequestDto.java +++ b/src/main/java/roomescape/domain/Dto/RequestDto.java @@ -7,6 +7,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; @Data public class RequestDto { @@ -15,10 +16,10 @@ public class RequestDto { private String time; public Reservation toReservation() { - Reservation reservation = new Reservation(); - reservation.setName(name); - reservation.setDate(date); - reservation.setTime(time); - return reservation; + LocalDateTime reservationDateTime = LocalDateTime.of( + LocalDate.parse(date), + LocalTime.parse(time) + ); + return new Reservation(name, reservationDateTime); } } \ No newline at end of file diff --git a/src/main/java/roomescape/domain/Dto/ResponseDto.java b/src/main/java/roomescape/domain/Dto/ResponseDto.java index 87a8503cd..de5d2eb9b 100644 --- a/src/main/java/roomescape/domain/Dto/ResponseDto.java +++ b/src/main/java/roomescape/domain/Dto/ResponseDto.java @@ -14,13 +14,21 @@ public class ResponseDto { private String date; private String time; + public ResponseDto(Long id, String name, String date, String time) { + this.id = id; + this.name = name; + this.date = date; + this.time = time; + } + public static ResponseDto makeResponse(Reservation reservation) { - ResponseDto responseDto = new ResponseDto(); - responseDto.id = reservation.getId(); - responseDto.name = reservation.getName(); - responseDto.date = reservation.getDate(); - responseDto.time = reservation.getTime(); - return responseDto; + LocalDateTime reservationDateTime = reservation.getLocalDateTime(); + return new ResponseDto( + reservation.getId(), + reservation.getName(), + reservationDateTime.toLocalDate().toString(), + reservationDateTime.toLocalTime().toString() + ); } } \ No newline at end of file diff --git a/src/main/java/roomescape/domain/Model/Reservation.java b/src/main/java/roomescape/domain/Model/Reservation.java index 9fb0cbbc6..4a393d268 100644 --- a/src/main/java/roomescape/domain/Model/Reservation.java +++ b/src/main/java/roomescape/domain/Model/Reservation.java @@ -9,7 +9,18 @@ public class Reservation { private Long id; private String name; - private String date; - private String time; + private LocalDateTime localDateTime; + public Reservation() { + } + + public Reservation(Long id, String name, LocalDateTime localDateTime) { + this.id = id; + this.name = name; + this.localDateTime = localDateTime; + } + public Reservation(String name, LocalDateTime localDateTime) { + this.name = name; + this.localDateTime = localDateTime; + } } diff --git a/src/main/java/roomescape/domain/Repository/BasicRepository.java b/src/main/java/roomescape/domain/Repository/BasicRepository.java new file mode 100644 index 000000000..88852795f --- /dev/null +++ b/src/main/java/roomescape/domain/Repository/BasicRepository.java @@ -0,0 +1,14 @@ +package roomescape.domain.Repository; + +import roomescape.domain.Model.Reservation; + +import java.util.List; + + +public interface BasicRepository { + public Reservation save(Reservation reservation); + + public List findAll(); + + public void deleteReservation(Long id); +} diff --git a/src/main/java/roomescape/domain/Repository/JdbcReservationRepository.java b/src/main/java/roomescape/domain/Repository/JdbcReservationRepository.java new file mode 100644 index 000000000..095b4313a --- /dev/null +++ b/src/main/java/roomescape/domain/Repository/JdbcReservationRepository.java @@ -0,0 +1,56 @@ +package roomescape.domain.Repository; + +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.stereotype.Repository; +import roomescape.domain.Model.Reservation; +import roomescape.domain.exception.NotFoundReservationException; + +import java.sql.PreparedStatement; +import java.time.LocalDateTime; +import java.util.List; + +@Repository +public class JdbcReservationRepository implements BasicRepository{ + private final JdbcTemplate jdbcTemplate; + + public JdbcReservationRepository(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @Override + public List findAll() { + String sql = "select * from reservation"; + return jdbcTemplate.query(sql, (rs, rowNum) -> new Reservation( + rs.getLong("id"), + rs.getString("name"), + rs.getObject("reservation_date_time", LocalDateTime.class) + )); + } + + @Override + public Reservation save(Reservation reservation) { + String sql = "INSERT INTO reservation (name, reservation_date_time) VALUES (?, ?)"; + + GeneratedKeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"}); + ps.setString(1, reservation.getName()); + ps.setObject(2, reservation.getLocalDateTime()); + return ps; + }, keyHolder); + + long pk = keyHolder.getKey().longValue(); + return new Reservation(pk, reservation.getName(), reservation.getLocalDateTime()); + } + + @Override + public void deleteReservation(final Long id) { + String sql = "DELETE FROM reservation WHERE id = ?"; + int updateCount = jdbcTemplate.update(sql, id); + if (updateCount == 0) { + throw new NotFoundReservationException("예약을 찾을 수 없습니다."); + } + } +} diff --git a/src/main/java/roomescape/web/Controller/ReservationController.java b/src/main/java/roomescape/web/Controller/ReservationController.java index 80a38176b..fd5c5d359 100644 --- a/src/main/java/roomescape/web/Controller/ReservationController.java +++ b/src/main/java/roomescape/web/Controller/ReservationController.java @@ -4,14 +4,14 @@ import lombok.Data; import lombok.RequiredArgsConstructor; import org.apache.catalina.connector.Response; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import roomescape.domain.Dto.RequestDto; import roomescape.domain.Dto.ResponseDto; import roomescape.domain.Model.Reservation; -import roomescape.domain.Repository.ReservationRepository; -import roomescape.web.Service.ReservationService; +import roomescape.domain.Repository.BasicRepository; import java.lang.reflect.Member; @@ -24,9 +24,12 @@ import static java.util.stream.Collectors.toList; @Controller -@RequiredArgsConstructor public class ReservationController { - private final ReservationService reservationService; + private final BasicRepository basicRepository; + + public ReservationController(@Qualifier("jdbcReservationRepository") BasicRepository basicRepository) { + this.basicRepository = basicRepository; + } @GetMapping("/reservation") public String reservation(){ @@ -36,7 +39,7 @@ public String reservation(){ @GetMapping ("/reservations") @ResponseBody public ResponseEntity> checkReservation(){ - List reservations = reservationService.findAll(); + List reservations = basicRepository.findAll(); List responseDtos = reservations.stream() .map(ResponseDto::makeResponse) .toList(); @@ -46,7 +49,7 @@ public ResponseEntity> checkReservation(){ @ResponseBody public ResponseEntity addReservation(@RequestBody RequestDto requestDto){ - Reservation reservation = reservationService.join(requestDto.toReservation()); + Reservation reservation = basicRepository.save(requestDto.toReservation()); ResponseDto responseDto = ResponseDto.makeResponse(reservation); URI location = URI.create("/reservations/"+responseDto.getId()); return ResponseEntity.created(location).body(responseDto); @@ -54,7 +57,7 @@ public ResponseEntity addReservation(@RequestBody RequestDto reques @DeleteMapping("/reservations/{id}") public ResponseEntity deleteReservation(@PathVariable Long id) { - reservationService.delete(id); + basicRepository.deleteReservation(id); return ResponseEntity.noContent().build(); } diff --git a/src/main/java/roomescape/web/Service/ReservationService.java b/src/main/java/roomescape/web/Service/ReservationService.java deleted file mode 100644 index 1439ec27d..000000000 --- a/src/main/java/roomescape/web/Service/ReservationService.java +++ /dev/null @@ -1,39 +0,0 @@ -package roomescape.web.Service; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import roomescape.domain.Model.Reservation; -import roomescape.domain.Repository.ReservationRepository; -import roomescape.domain.exception.NoDataException; -import roomescape.domain.exception.NotFoundReservationException; - -import java.util.ArrayList; -import java.util.List; - -@Service -@RequiredArgsConstructor -public class ReservationService { - private final ReservationRepository reservationRepository; - - public Reservation join(Reservation reservation) { - validateReservation(reservation); - return reservationRepository.save(reservation); - } - - private void validateReservation(Reservation reservation) { - if(reservation.getTime().isBlank() || reservation.getDate().isBlank() || reservation.getName().isBlank()) - throw new NoDataException("데이터가 비어있습니다."); - } - - public Reservation findById(Long id) { - return reservationRepository.findById(id); - } - - public List findAll() { - return reservationRepository.findAll(); - } - - public Reservation delete(Long id){ - return reservationRepository.deleteReservation(id); - } -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e69de29bb..f597afeef 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console +spring.datasource.url=jdbc:h2:mem:database \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 000000000..5b5431b00 --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS reservation; + +CREATE TABLE reservation +( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + reservation_date_time TIMESTAMP NOT NULL +); \ No newline at end of file diff --git a/src/test/java/roomescape/JdbcTest.java b/src/test/java/roomescape/JdbcTest.java new file mode 100644 index 000000000..a2df9c520 --- /dev/null +++ b/src/test/java/roomescape/JdbcTest.java @@ -0,0 +1,82 @@ +package roomescape; + +import io.restassured.RestAssured; +import io.restassured.http.ContentType; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.annotation.DirtiesContext; +import roomescape.domain.Dto.ResponseDto; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +@SuppressWarnings("NonAsciiCharacters") +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +public class JdbcTest { + @Autowired + private JdbcTemplate jdbcTemplate; + + @Test + void 오단계() { + try (Connection connection = jdbcTemplate.getDataSource().getConnection()) { + assertThat(connection).isNotNull(); + assertThat(connection.getCatalog()).isEqualTo("DATABASE"); + assertThat(connection.getMetaData().getTables(null, null, "RESERVATION", null).next()).isTrue(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + @Test + void 육단계() { + jdbcTemplate.update( + "INSERT INTO reservation (name, reservation_date_time) VALUES (?, ?) ", + "브라운", "2023-08-05T15:40" + ); + + List reservations = RestAssured.given().log().all() + .when().get("/reservations") + .then().log().all() + .statusCode(200).extract() + .jsonPath().getList(".", ResponseDto.class); + + Integer count = jdbcTemplate.queryForObject("SELECT count(1) from reservation", Integer.class); + + assertThat(reservations.size()).isEqualTo(count); + } + + @Test + void 칠단계() { + Map params = new HashMap<>(); + params.put("name", "브라운"); + params.put("date", "2023-08-05"); + params.put("time", "10:00"); + + RestAssured.given().log().all() + .contentType(ContentType.JSON) + .body(params) + .when().post("/reservations") + .then().log().all() + .statusCode(201) + .header("Location", "/reservations/1"); + + Integer count = jdbcTemplate.queryForObject("SELECT count(1) from reservation", Integer.class); + assertThat(count).isEqualTo(1); + + RestAssured.given().log().all() + .when().delete("/reservations/1") + .then().log().all() + .statusCode(204); + + Integer countAfterDelete = jdbcTemplate.queryForObject("SELECT count(1) from reservation", Integer.class); + assertThat(countAfterDelete).isEqualTo(0); + } +} From 19cd1da004fdddea02cf03cd90e052229a357481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A3=BC=EB=B3=91=EC=A3=BC?= Date: Tue, 21 May 2024 10:33:00 +0900 Subject: [PATCH 5/6] jdbc add --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f597afeef..b63619d73 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,3 +1,3 @@ spring.h2.console.enabled=true spring.h2.console.path=/h2-console -spring.datasource.url=jdbc:h2:mem:database \ No newline at end of file +spring.datasource.url=jdbc:h2:mem:database From b2492d5249cef82bedd0867c1838057aeece8621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A3=BC=EB=B3=91=EC=A3=BC?= Date: Thu, 23 May 2024 21:32:38 +0900 Subject: [PATCH 6/6] =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roomescape/domain/Repository/JdbcReservationRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/roomescape/domain/Repository/JdbcReservationRepository.java b/src/main/java/roomescape/domain/Repository/JdbcReservationRepository.java index 095b4313a..bf16e2fc3 100644 --- a/src/main/java/roomescape/domain/Repository/JdbcReservationRepository.java +++ b/src/main/java/roomescape/domain/Repository/JdbcReservationRepository.java @@ -21,7 +21,7 @@ public JdbcReservationRepository(JdbcTemplate jdbcTemplate) { @Override public List findAll() { - String sql = "select * from reservation"; + String sql = "SELECT * FROM reservation"; return jdbcTemplate.query(sql, (rs, rowNum) -> new Reservation( rs.getLong("id"), rs.getString("name"),