-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Spring JDBC] 김이화 미션 제출합니다. #295
Changes from 6 commits
17cd0d9
13cd4b3
63d8d62
a9d5050
7a8a744
fdfdee3
04f3a9b
3d825dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package roomescape.controller; | ||
|
||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
import roomescape.exception.InvalidReservationException; | ||
import roomescape.model.Reservation; | ||
import roomescape.respository.ReservationRepository; | ||
|
||
import java.net.URI; | ||
import java.util.List; | ||
import java.util.concurrent.atomic.AtomicLong; | ||
|
||
@RestController | ||
@RequestMapping("/reservations") | ||
public class ReservationController { | ||
private AtomicLong index = new AtomicLong(1); | ||
private final ReservationRepository reservationRepository; | ||
|
||
public ReservationController(ReservationRepository reservationRepository) { | ||
this.reservationRepository = reservationRepository; | ||
} | ||
|
||
@GetMapping | ||
@ResponseBody | ||
public List<Reservation> getReservations() { | ||
return reservationRepository.findAllReservations(); | ||
} | ||
|
||
@GetMapping("/{id}") | ||
@ResponseBody | ||
public Reservation findReservationById(@PathVariable Long id) { | ||
return reservationRepository.findReservationById(id); | ||
} | ||
Comment on lines
+27
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기에서는 왜 따로 ResponseEntity 활용을 안했는지 궁금합니당 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
@PostMapping | ||
@ResponseBody | ||
public ResponseEntity<Reservation> createReservation(@RequestBody Reservation reservation) { | ||
validateReservation(reservation); | ||
|
||
Long id = index.getAndIncrement(); | ||
|
||
Reservation newReservation = new Reservation(id, reservation.getName(), reservation.getDate(), reservation.getTime()); | ||
reservationRepository.insert(newReservation); | ||
|
||
return ResponseEntity.created(URI.create("/reservations/" + newReservation.getId())).body(newReservation); | ||
} | ||
|
||
@DeleteMapping("/{id}") | ||
@ResponseBody | ||
public ResponseEntity<Void> deleteReservation(@PathVariable Long id) { | ||
reservationRepository.delete(id); | ||
return ResponseEntity.noContent().build(); | ||
} | ||
|
||
private void validateReservation(Reservation reservation) { | ||
if (reservation.getName() == null || reservation.getName().isEmpty()) { | ||
throw new InvalidReservationException("name", "이름이 필요합니다."); | ||
} | ||
if (reservation.getDate() == null || reservation.getDate().isEmpty()) { | ||
throw new InvalidReservationException("date", "날짜가 필요합니다."); | ||
} | ||
if (reservation.getTime() == null || reservation.getTime().isEmpty()) { | ||
throw new InvalidReservationException("time", "시간이 필요합니다."); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. validateReservation 메소드 분리 할 수 있지 않을까요?! 중복된 코드를 줄이면 가독성이 좋아질 것 같아요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [spring core]에 리팩토링 해서 넣었습니다. 클래스로 나눠서 예외 처리 패키지에 넣었는데, 이걸 말씀하시는 게 맞을까요? |
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package roomescape.controller; | ||
|
||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
|
||
@Controller | ||
public class WelcomeController { | ||
@GetMapping("/") | ||
public String welcome() { | ||
return "index"; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 홈페이지 컨트롤러와 CR(U)D 컨트롤러를 따로 나눈 거 좋아보여요! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package roomescape.exception; | ||
|
||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.ControllerAdvice; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.context.request.WebRequest; | ||
|
||
@ControllerAdvice | ||
public class GlobalExceptionHandler { | ||
|
||
@ExceptionHandler(NotFoundReservationException.class) | ||
public ResponseEntity<String> handleNotFoundReservationException(NotFoundReservationException e, WebRequest request) { | ||
String message = "예약을 찾을 수 없습니다: " + e.getReservationId(); | ||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body((e.getMessage())); | ||
} | ||
|
||
@ExceptionHandler(InvalidReservationException.class) | ||
public ResponseEntity<String> handleInvalidReservationException(InvalidReservationException e, WebRequest request) { | ||
String message = e.getFieldName() + "'의 값이 유용하지 않습니다: " + e.getMessage(); | ||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage()); | ||
} | ||
|
||
@ExceptionHandler(Exception.class) | ||
public ResponseEntity<String> handleGlobalException(Exception e, WebRequest request) { | ||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("예기치 않은 오류가 발생했습니다: " + e.getMessage()); | ||
} | ||
|
||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 커스텀 예외처리 멋있어용👍👍 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package roomescape.exception; | ||
|
||
public class InvalidReservationException extends RuntimeException{ | ||
private String fieldName; | ||
|
||
public InvalidReservationException(String fieldName, String message) { | ||
super(message); | ||
this.fieldName = fieldName; | ||
} | ||
|
||
public String getFieldName() { | ||
return fieldName; | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exception 명확하게 구분한 것 좋은 것 같아요! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package roomescape.exception; | ||
|
||
public class NotFoundReservationException extends RuntimeException{ | ||
private Long reservationId; | ||
public NotFoundReservationException(Long reservationId) { | ||
super("예약을 찾을 수 없습니다: " + reservationId); | ||
this.reservationId = reservationId; | ||
} | ||
|
||
public Long getReservationId() { | ||
return reservationId; | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RequestDto와 ResponseDto를 만들어 엔티티 분리하면 더 좋을 것 같아요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [spring core]에 리팩토링 해서 만들었습니다! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package roomescape.model; | ||
|
||
public class Reservation { | ||
private Long id; | ||
private String name; | ||
private String date; | ||
private String time; | ||
|
||
public Reservation(long id, String name, String date, String time) { | ||
this.id = id; | ||
this.name = name; | ||
this.date = date; | ||
this.time = time; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public String getDate() { | ||
return date; | ||
} | ||
|
||
public String getTime() { | ||
return time; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package roomescape.respository; | ||
|
||
import org.springframework.dao.EmptyResultDataAccessException; | ||
import org.springframework.jdbc.core.JdbcTemplate; | ||
import org.springframework.jdbc.core.RowMapper; | ||
import org.springframework.stereotype.Repository; | ||
import roomescape.exception.NotFoundReservationException; | ||
import roomescape.model.Reservation; | ||
|
||
import java.util.List; | ||
|
||
@Repository | ||
public class ReservationRepository { | ||
|
||
private JdbcTemplate jdbcTemplate; | ||
|
||
public ReservationRepository(JdbcTemplate jdbcTemplate) { | ||
this.jdbcTemplate = jdbcTemplate; | ||
} | ||
|
||
private final RowMapper<Reservation> rowMapper = (resultSet, rowNum) -> { | ||
Reservation reservation = new Reservation( | ||
resultSet.getLong("id"), | ||
resultSet.getString("name"), | ||
resultSet.getString("date"), | ||
resultSet.getString("time")); | ||
return reservation; | ||
}; | ||
|
||
public List<Reservation> findAllReservations() { | ||
String sql = "SELECT id, name, date, time FROM reservation"; | ||
return jdbcTemplate.query(sql, rowMapper); | ||
} | ||
|
||
public Reservation findReservationById(Long id) { | ||
String sql = "SELECT id, name, date, time FROM reservation where id = ?"; | ||
try { | ||
return jdbcTemplate.queryForObject(sql, rowMapper, id); | ||
} catch (EmptyResultDataAccessException e) { | ||
throw new NotFoundReservationException(id); | ||
} | ||
} | ||
Comment on lines
+38
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오 원래 DAO에 대해서 잘 알고 있었나요? 능숙해보여요
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아뇨 초록 스터디 학습테스트에서 열심히 해봤는데도 사용하는데 어려움이 많았습니다 ㅠㅠ |
||
|
||
public void insert(Reservation reservation) { | ||
String sql = "INSERT INTO reservation(name, date, time) VALUES (?, ?, ?)"; | ||
jdbcTemplate.update(sql, reservation.getName(), reservation.getDate(), reservation.getTime()); | ||
} | ||
|
||
public int delete(Long id) { | ||
String sql = "DELETE FROM reservation WHERE id = ?"; | ||
int row = jdbcTemplate.update(sql, id); | ||
if (row == 0) { | ||
throw new NotFoundReservationException(id); | ||
} | ||
return row; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
spring.h2.console.enabled=true | ||
spring.h2.console.path=/h2-console | ||
spring.datasource.url=jdbc:h2:mem:database | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
CREATE TABLE reservation | ||
( | ||
id BIGINT NOT NULL AUTO_INCREMENT, | ||
name VARCHAR(255) NOT NULL, | ||
date VARCHAR(255) NOT NULL, | ||
time VARCHAR(255) NOT NULL, | ||
PRIMARY KEY (id) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
미션 요구 조건에 제거하라고 나와 있어서 제거하고 구현하는 게 좋을 것 같아요!
(혹시나 제가 요구 조건을 잘못 이해한 거라면 말씀해주세용~)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
헉 지워서 제출하겠습니다