Skip to content

Commit

Permalink
10단계 - 계층화 리팩터링
Browse files Browse the repository at this point in the history
  • Loading branch information
jermany17 committed Nov 26, 2024
1 parent 61fd1c9 commit 45d4f6c
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 105 deletions.
73 changes: 10 additions & 63 deletions src/main/java/roomescape/controller/ReservationController.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,24 @@
package roomescape.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.Controller;
import org.springframework.web.bind.annotation.*;
import roomescape.exception.NotFoundReservationException;
import roomescape.model.Reservation;
import roomescape.model.ReservationRequest;
import roomescape.model.Time;
import roomescape.model.ReservationRequest;;
import roomescape.service.ReservationService;

import java.net.URI;
import java.sql.PreparedStatement;
import java.util.List;

@Controller
public class ReservationController {

private final JdbcTemplate jdbcTemplate;
private final ReservationService reservationService;

public ReservationController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
public ReservationController(ReservationService reservationService) {
this.reservationService = reservationService;
}

private final RowMapper<Reservation> reservationRowMapper = (rs, rowNum) -> new Reservation(
rs.getLong("reservation_id"),
rs.getString("name"),
rs.getString("date"),
new Time(rs.getLong("time_id"), rs.getString("time_value"))
);

// 예약 관리 페이지
@GetMapping("/reservation")
public String reservationPage() {
Expand All @@ -43,61 +29,22 @@ public String reservationPage() {
@GetMapping("/reservations")
@ResponseBody
public ResponseEntity<List<Reservation>> getReservations() {
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
""";
List<Reservation> reservations = jdbcTemplate.query(sql, reservationRowMapper);
List<Reservation> reservations = reservationService.getReservations();
return ResponseEntity.ok(reservations);
}

// 예약 추가
@PostMapping("/reservations")
@ResponseBody
public ResponseEntity<Reservation> addReservation(@RequestBody ReservationRequest request) {
request.validateAndSetTimeId(jdbcTemplate);

// 예약 추가
String sql = "INSERT INTO reservation (name, date, time_id) VALUES (?, ?, ?)";
KeyHolder keyHolder = new GeneratedKeyHolder();

jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
ps.setString(1, request.getName());
ps.setString(2, request.getDate());
ps.setLong(3, request.getTimeId());
return ps;
}, keyHolder);

Long id = keyHolder.getKey().longValue();

String timeQuery = "SELECT time FROM time WHERE id = ?";
String timeValue = jdbcTemplate.queryForObject(timeQuery, String.class, request.getTime());

Reservation newReservation = new Reservation(id, request.getName(), request.getDate(),
new Time(request.getTimeId(), timeValue));


return ResponseEntity.created(URI.create("/reservations/" + id)).body(newReservation);
Reservation newReservation = reservationService.addReservation(request);
return ResponseEntity.created(URI.create("/reservations/" + newReservation.getId())).body(newReservation);
}

// 예약 삭제
@DeleteMapping("/reservations/{id}")
public ResponseEntity<Void> deleteReservation(@PathVariable Long id) {
String sql = "DELETE FROM reservation WHERE id = ?";
int rowsAffected = jdbcTemplate.update(sql, id);

if (rowsAffected > 0) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}

throw new NotFoundReservationException("삭제할 예약이 없습니다.");
reservationService.deleteReservation(id);
return ResponseEntity.noContent().build();
}
}
49 changes: 11 additions & 38 deletions src/main/java/roomescape/controller/TimeController.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
package roomescape.controller;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.Controller;
import org.springframework.web.bind.annotation.*;
import roomescape.model.Time;
import roomescape.service.TimeService;

import java.net.URI;
import java.sql.PreparedStatement;
import java.util.List;

@Controller
public class TimeController {

private final JdbcTemplate jdbcTemplate;
private final TimeService timeService;

public TimeController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
public TimeController(TimeService timeService) {
this.timeService = timeService;
}

private final RowMapper<Time> timeRowMapper = (rs, rowNum) -> new Time(
rs.getLong("id"),
rs.getString("time")
);

// 시간 관리 페이지
@GetMapping("/time")
public String reservationPage() {
Expand All @@ -39,39 +28,23 @@ public String reservationPage() {
@GetMapping("/times")
@ResponseBody
public ResponseEntity<List<Time>> getTimes() {
String sql = "SELECT id, time FROM time";
List<Time> times = jdbcTemplate.query(sql, timeRowMapper);
List<Time> times = timeService.getAllTimes();
return ResponseEntity.ok(times);
}

// 시간 추가
@PostMapping("/times")
@ResponseBody
public ResponseEntity<Time> addTime(@RequestBody Time request) {
String sql = "INSERT INTO time (time) VALUES (?)";
KeyHolder keyHolder = new GeneratedKeyHolder();

jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
ps.setString(1, request.getTime());
return ps;
}, keyHolder);

Long id = keyHolder.getKey().longValue();
Time newTime = new Time(id, request.getTime());

return ResponseEntity.created(URI.create("/times/" + id)).body(newTime);
Time newTime = timeService.addTime(request);
return ResponseEntity.created(URI.create("/times/" + newTime.getId())).body(newTime);
}

// 시간 삭제
@DeleteMapping("/times/{id}")
@ResponseBody
public ResponseEntity<Void> deleteTime(@PathVariable Long id) {
String sql = "DELETE FROM time WHERE id = ?";
int rowsAffected = jdbcTemplate.update(sql, id);

if (rowsAffected > 0) {
return ResponseEntity.noContent().build();
}

return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
timeService.deleteTime(id);
return ResponseEntity.noContent().build();
}
}
74 changes: 74 additions & 0 deletions src/main/java/roomescape/dao/ReservationDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package roomescape.dao;

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.model.Reservation;
import roomescape.model.ReservationRequest;
import roomescape.model.Time;

import java.sql.PreparedStatement;
import java.util.List;

@Repository
public class ReservationDao {

private final JdbcTemplate jdbcTemplate;

private final RowMapper<Reservation> reservationRowMapper = (rs, rowNum) -> new Reservation(
rs.getLong("reservation_id"),
rs.getString("name"),
rs.getString("date"),
new Time(rs.getLong("time_id"), rs.getString("time_value"))
);

public ReservationDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}

public List<Reservation> 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, reservationRowMapper);
}

public Reservation save(ReservationRequest request) {
String sql = "INSERT INTO reservation (name, date, time_id) VALUES (?, ?, ?)";
KeyHolder keyHolder = new GeneratedKeyHolder();

jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
ps.setString(1, request.getName());
ps.setString(2, request.getDate());
ps.setLong(3, request.getTimeId());
return ps;
}, keyHolder);

Long id = keyHolder.getKey().longValue();

String timeQuery = "SELECT time FROM time WHERE id = ?";
String timeValue = jdbcTemplate.queryForObject(timeQuery, String.class, request.getTimeId());

return new Reservation(id, request.getName(), request.getDate(), new Time(request.getTimeId(), timeValue));
}

public int deleteById(Long id) {
String sql = "DELETE FROM reservation WHERE id = ?";
return jdbcTemplate.update(sql, id);
}
}
50 changes: 50 additions & 0 deletions src/main/java/roomescape/dao/TimeDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package roomescape.dao;

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.model.Time;

import java.sql.PreparedStatement;
import java.util.List;

@Repository
public class TimeDao {

private final JdbcTemplate jdbcTemplate;

private final RowMapper<Time> timeRowMapper = (rs, rowNum) -> new Time(
rs.getLong("id"),
rs.getString("time")
);

public TimeDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public List<Time> findAll() {
String sql = "SELECT id, time FROM time";
return jdbcTemplate.query(sql, timeRowMapper);
}

public Time save(Time time) {
String sql = "INSERT INTO time (time) VALUES (?)";
KeyHolder keyHolder = new GeneratedKeyHolder();

jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
ps.setString(1, time.getTime());
return ps;
}, keyHolder);

Long id = keyHolder.getKey().longValue();
return new Time(id, time.getTime());
}

public int deleteById(Long id) {
String sql = "DELETE FROM time WHERE id = ?";
return jdbcTemplate.update(sql, id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
public class GlobalExceptionHandler {

// 특정 예외를 처리하는 메서드를 정의

@ExceptionHandler(NotFoundReservationException.class)
public ResponseEntity<String> handleNotFoundReservationException(NotFoundReservationException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
Expand All @@ -20,4 +21,9 @@ public ResponseEntity<String> handleNotFoundReservationException(NotFoundReserva
public ResponseEntity<String> handleInvalidReservationException(InvalidReservationException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}

@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
3 changes: 3 additions & 0 deletions src/main/java/roomescape/model/Time.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public String getTime() {
}

public void setTime(String time) {
if (time == null || time.trim().isEmpty()) {
throw new IllegalArgumentException("시간 값이 비어 있습니다.");
}
this.time = time;
}
}
35 changes: 35 additions & 0 deletions src/main/java/roomescape/service/ReservationService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package roomescape.service;

import org.springframework.stereotype.Service;
import roomescape.dao.ReservationDao;
import roomescape.exception.NotFoundReservationException;
import roomescape.model.Reservation;
import roomescape.model.ReservationRequest;

import java.util.List;

@Service
public class ReservationService {

private final ReservationDao reservationDao;

public ReservationService(ReservationDao reservationDao) {
this.reservationDao = reservationDao;
}

public List<Reservation> getReservations() {
return reservationDao.findAll();
}

public Reservation addReservation(ReservationRequest request) {
request.validateAndSetTimeId(reservationDao.getJdbcTemplate());
return reservationDao.save(request);
}

public void deleteReservation(Long id) {
int rowsAffected = reservationDao.deleteById(id);
if (rowsAffected == 0) {
throw new NotFoundReservationException("삭제할 예약이 없습니다.");
}
}
}
Loading

0 comments on commit 45d4f6c

Please sign in to comment.