-
Notifications
You must be signed in to change notification settings - Fork 119
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 Core] 이동호 미션 제출합니다. #264
base: plusultracode
Are you sure you want to change the base?
Changes from 3 commits
06583e5
fbdc5c1
0c9f3db
2c704f1
6443dcd
2207bf3
1f39026
e903bef
098b99c
6cb8adc
cf79545
a5aa063
1f92290
6ea0ac4
89ae934
9f0e681
90ea520
7e002f3
0be43a7
c859908
6c59295
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 |
---|---|---|
@@ -1,63 +1,53 @@ | ||
package roomescape.reservation.controller; | ||
|
||
|
||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.*; | ||
import roomescape.reservation.db.ReservationEntity; | ||
import roomescape.reservation.model.ReservationRequest; | ||
import roomescape.reservation.dto.ReservationRequest; | ||
import roomescape.reservation.dto.ReservationResponse; | ||
import roomescape.reservation.service.ReservationService; | ||
|
||
import javax.net.ssl.SSLEngineResult; | ||
import java.net.URI; | ||
import java.util.List; | ||
|
||
@Controller | ||
@RestController | ||
@RequiredArgsConstructor | ||
public class ReservationApiController { | ||
|
||
private final ReservationService reservationService; | ||
|
||
@GetMapping("/reservation") | ||
public String reservation() { | ||
return "reservation"; | ||
} | ||
|
||
@GetMapping("/reservations") | ||
public ResponseEntity<List<ReservationEntity>> reservations() { | ||
|
||
List<ReservationEntity> lists = reservationService.findAllList(); | ||
public ResponseEntity<List<ReservationResponse>> reservations() { | ||
List<ReservationResponse> responseList = reservationService.findAllReservations(); | ||
|
||
return ResponseEntity.status(HttpStatus.OK) | ||
.body(lists); | ||
return ResponseEntity | ||
.status(HttpStatus.OK) | ||
.body(responseList); | ||
} | ||
|
||
@PostMapping("/reservations") | ||
public ResponseEntity<ReservationEntity> createReservation( | ||
public ResponseEntity<ReservationResponse> addReservation( | ||
@Valid | ||
@RequestBody ReservationRequest reservationRequest | ||
) { | ||
|
||
ReservationEntity reservationEntity = reservationService.insertReservation(reservationRequest); | ||
ReservationResponse response = reservationService.addReservation(reservationRequest); | ||
|
||
|
||
HttpHeaders headers = new HttpHeaders(); | ||
headers.setLocation(URI.create("/reservations/" + Long.toString(reservationEntity.getId()))); | ||
|
||
return ResponseEntity.status(HttpStatus.CREATED) | ||
.headers(headers) | ||
.body(reservationEntity); | ||
return ResponseEntity.created(URI.create("/reservations/" + response.getId())) | ||
.body(response); | ||
} | ||
|
||
@DeleteMapping("/reservations/{id}") | ||
public ResponseEntity<Void> deleteReservation( | ||
@PathVariable Long id | ||
) { | ||
reservationService.cancelReservation(id); | ||
|
||
reservationService.deleteReservation(id); | ||
|
||
return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); | ||
return ResponseEntity.noContent() | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package roomescape.reservation.controller; | ||
|
||
|
||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
|
||
@Controller | ||
public class ReservationController { | ||
|
||
@GetMapping("/reservation") | ||
public String reservation() { | ||
return "new-reservation"; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,15 @@ | ||
package roomescape.reservation.db; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
import roomescape.time.db.TimeEntity; | ||
|
||
@Data | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
@Builder | ||
public class ReservationEntity { | ||
|
||
private Long id; | ||
|
||
private String name; | ||
|
||
private String date; | ||
private TimeEntity timeEntity; | ||
|
||
private String time; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,83 @@ | ||
package roomescape.reservation.db; | ||
|
||
import roomescape.reservation.model.ReservationRequest; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.annotation.Primary; | ||
import org.springframework.dao.EmptyResultDataAccessException; | ||
import org.springframework.jdbc.core.JdbcTemplate; | ||
import org.springframework.jdbc.core.RowMapper; | ||
import org.springframework.jdbc.support.GeneratedKeyHolder; | ||
import org.springframework.jdbc.support.KeyHolder; | ||
import org.springframework.stereotype.Repository; | ||
import roomescape.time.db.TimeEntity; | ||
|
||
import java.sql.PreparedStatement; | ||
import java.util.List; | ||
|
||
@Primary | ||
@Repository | ||
@RequiredArgsConstructor | ||
public class ReservationRepository implements ReservationRepositoryImpl { | ||
|
||
private final JdbcTemplate jdbcTemplate; | ||
|
||
private final RowMapper<ReservationEntity> rowMapper = (rs, rowNum) -> { | ||
TimeEntity timeEntity = new TimeEntity(rs.getLong("time_id"), rs.getString("time_value")); | ||
ReservationEntity reservationEntity = ReservationEntity.builder() | ||
.id(rs.getLong("id")) | ||
.name(rs.getString("name")) | ||
.date(rs.getString("date")) | ||
.timeEntity(timeEntity) | ||
.build(); | ||
|
||
return reservationEntity; | ||
}; | ||
|
||
|
||
@Override | ||
public List<ReservationEntity> findAll() { | ||
String sql = "SELECT r.id as reservation_id, r.name, r.date, t.id as time_id, t.time as time_value " + | ||
"FROM reservation as r INNER JOIN time as t ON r.time_id = t.id"; | ||
|
||
return jdbcTemplate.query(sql, rowMapper); | ||
} | ||
|
||
@Override | ||
public ReservationEntity save(ReservationEntity reservationEntity) { | ||
String sql = "INSERT INTO reservation (name,date,time_id) VALUES(?,?,?)"; | ||
|
||
public interface ReservationRepository { | ||
KeyHolder keyHolder = new GeneratedKeyHolder(); | ||
|
||
jdbcTemplate.update(connection -> { | ||
PreparedStatement ps = connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS); | ||
ps.setString(1, reservationEntity.getName()); | ||
ps.setObject(2, reservationEntity.getDate()); | ||
ps.setLong(3, reservationEntity.getTimeEntity().getId()); | ||
return ps; | ||
|
||
List<ReservationEntity> findAllList(); | ||
}, keyHolder); | ||
|
||
int countReservation(); | ||
Long generatedId = keyHolder.getKey().longValue(); | ||
reservationEntity.setId(generatedId); | ||
return reservationEntity; | ||
|
||
ReservationEntity findReservationById(Long id); | ||
} | ||
|
||
ReservationEntity insertReservation(ReservationRequest reservationRequest); | ||
@Override | ||
public ReservationEntity findById(Long id) { | ||
String sql = "SELECT r.id as reservation_id, r.name, r.date, t.id as time_id, t.time as time_value " + | ||
"FROM reservation as r INNER JOIN time as t ON r.time_id = t.id " + | ||
"WHERE r.id = ?"; | ||
try { | ||
return jdbcTemplate.queryForObject(sql, rowMapper, id); | ||
} catch (EmptyResultDataAccessException e) { | ||
return null; | ||
} | ||
} | ||
|
||
void deleteReservation(Long id); | ||
@Override | ||
public void deleteById(Long id) { | ||
String sql = "DELETE FROM reservation WHERE id = ?"; | ||
jdbcTemplate.update(sql, id); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,14 @@ | ||
package roomescape.reservation.db; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.jdbc.core.JdbcTemplate; | ||
import org.springframework.jdbc.core.RowMapper; | ||
import org.springframework.jdbc.support.GeneratedKeyHolder; | ||
import org.springframework.stereotype.Repository; | ||
import roomescape.reservation.model.ReservationRequest; | ||
|
||
import java.sql.PreparedStatement; | ||
import java.util.List; | ||
|
||
@Repository | ||
@RequiredArgsConstructor | ||
public class ReservationRepositoryImpl implements ReservationRepository { | ||
|
||
private final JdbcTemplate jdbcTemplate; | ||
|
||
|
||
public final RowMapper<ReservationEntity> actorRowMapper = (resultSet, rowNum) -> { | ||
ReservationEntity reservationEntity = new ReservationEntity( | ||
resultSet.getLong("id"), | ||
resultSet.getString("name"), | ||
resultSet.getString("date"), | ||
resultSet.getString("time") | ||
); | ||
return reservationEntity; | ||
}; | ||
|
||
@Override | ||
public List<ReservationEntity> findAllList() { | ||
|
||
String sql = "select * from reservation"; | ||
return jdbcTemplate.query(sql, actorRowMapper); | ||
} | ||
|
||
@Override | ||
public int countReservation() { | ||
|
||
String sql = "select count(*) from reservation"; | ||
return jdbcTemplate.queryForObject(sql, Integer.class); | ||
} | ||
|
||
@Override | ||
public ReservationEntity findReservationById(Long id) { | ||
|
||
String sql = "select * from reservation where id=?"; | ||
return jdbcTemplate.queryForObject(sql, actorRowMapper, id); | ||
} | ||
|
||
@Override | ||
public ReservationEntity insertReservation(ReservationRequest reservationRequest) { | ||
|
||
String sql = "insert into reservation (name, date, time) values (?,?,?)"; | ||
|
||
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder(); | ||
jdbcTemplate.update(connection -> { | ||
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"}); | ||
ps.setString(1, reservationRequest.getName()); | ||
ps.setObject(2, reservationRequest.getDate()); | ||
ps.setObject(3, reservationRequest.getTime()); | ||
return ps; | ||
}, keyHolder); | ||
|
||
long generatedKey = keyHolder.getKey().longValue(); | ||
|
||
return findReservationById(generatedKey); | ||
|
||
public interface ReservationRepositoryImpl { | ||
|
||
} | ||
List<ReservationEntity> findAll(); | ||
|
||
@Override | ||
public void deleteReservation(Long id) { | ||
ReservationEntity save(ReservationEntity reservationEntity); | ||
|
||
String sql = "delete from reservation where id=?"; | ||
ReservationEntity findById(Long id); | ||
|
||
jdbcTemplate.update(sql, id); | ||
} | ||
void deleteById(Long id); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package roomescape.reservation.dto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Data | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class ReservationRequest { | ||
|
||
@NotBlank | ||
private String name; | ||
|
||
@NotBlank | ||
private String date; | ||
|
||
@NotBlank | ||
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. 여기서 timeId가 아닌 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. 감사합니다 상우님!! 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. 맞습니다. 저도 스프링 미션을 하면서 여러가지 오류들 때문에 꽤 고생을 했었습니다. |
||
private Long timeId; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package roomescape.reservation.dto; | ||
|
||
import lombok.Data; | ||
import roomescape.reservation.db.ReservationEntity; | ||
import roomescape.time.db.TimeEntity; | ||
|
||
@Data | ||
public class ReservationResponse { | ||
|
||
private Long id; | ||
private String name; | ||
private String date; | ||
private TimeEntity timeEntity; | ||
|
||
public static ReservationResponse from(ReservationEntity reservationEntity) { | ||
|
||
ReservationResponse dto = new ReservationResponse(); | ||
dto.setId(reservationEntity.getId()); | ||
dto.setName(reservationEntity.getName()); | ||
dto.setDate(reservationEntity.getDate()); | ||
dto.setTimeEntity(reservationEntity.getTimeEntity()); | ||
return dto; | ||
} | ||
|
||
} |
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.
저는 @GetMapping(value = "/reservations"), @PostMapping(value = "/reservations"), @DeleteMapping(value = "/reservations/{id}") 부분에서 "/reservations"가 중복되는걸 줄여주고 싶어서
@controller 어노테이션 위에 RequestMapping("/reservations")를 적어주었습니다.
이렇게 하면 중복되는 부분은 제거되어
@GetMapping(value = "/reservations") -> @GetMapping
@PostMapping(value = "/reservations") -> @PostMapping
@DeleteMapping(value = "/reservations/{id}") -> @DeleteMapping("/{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.
@RequsetMapping("/reservaations")를 사용하니
해당 클래스 안에 있는 @GetMapping @PostMapping에
중복되는 "/reservations"을 없앨 수 있게 되었습니다.
감사합니다 ^^