Skip to content

Commit 7589a0a

Browse files
committed
10단계 - 계층화 리팩터링
1 parent 26845b6 commit 7589a0a

File tree

9 files changed

+224
-105
lines changed

9 files changed

+224
-105
lines changed
Lines changed: 10 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,24 @@
11
package roomescape.controller;
22

3-
import org.springframework.http.HttpStatus;
43
import org.springframework.http.ResponseEntity;
5-
import org.springframework.jdbc.core.JdbcTemplate;
6-
import org.springframework.jdbc.core.RowMapper;
7-
import org.springframework.jdbc.support.GeneratedKeyHolder;
8-
import org.springframework.jdbc.support.KeyHolder;
94
import org.springframework.stereotype.Controller;
105
import org.springframework.web.bind.annotation.*;
11-
import roomescape.exception.NotFoundReservationException;
126
import roomescape.model.Reservation;
13-
import roomescape.model.ReservationRequest;
14-
import roomescape.model.Time;
7+
import roomescape.model.ReservationRequest;;
8+
import roomescape.service.ReservationService;
159

1610
import java.net.URI;
17-
import java.sql.PreparedStatement;
1811
import java.util.List;
1912

2013
@Controller
2114
public class ReservationController {
2215

23-
private final JdbcTemplate jdbcTemplate;
16+
private final ReservationService reservationService;
2417

25-
public ReservationController(JdbcTemplate jdbcTemplate) {
26-
this.jdbcTemplate = jdbcTemplate;
18+
public ReservationController(ReservationService reservationService) {
19+
this.reservationService = reservationService;
2720
}
2821

29-
private final RowMapper<Reservation> reservationRowMapper = (rs, rowNum) -> new Reservation(
30-
rs.getLong("reservation_id"),
31-
rs.getString("name"),
32-
rs.getString("date"),
33-
new Time(rs.getLong("time_id"), rs.getString("time_value"))
34-
);
35-
3622
// 예약 관리 페이지
3723
@GetMapping("/reservation")
3824
public String reservationPage() {
@@ -43,61 +29,22 @@ public String reservationPage() {
4329
@GetMapping("/reservations")
4430
@ResponseBody
4531
public ResponseEntity<List<Reservation>> getReservations() {
46-
String sql = """
47-
SELECT
48-
r.id as reservation_id,
49-
r.name,
50-
r.date,
51-
t.id as time_id,
52-
t.time as time_value
53-
FROM reservation as r
54-
INNER JOIN time as t
55-
ON r.time_id = t.id
56-
""";
57-
List<Reservation> reservations = jdbcTemplate.query(sql, reservationRowMapper);
32+
List<Reservation> reservations = reservationService.getReservations();
5833
return ResponseEntity.ok(reservations);
5934
}
6035

6136
// 예약 추가
6237
@PostMapping("/reservations")
6338
@ResponseBody
6439
public ResponseEntity<Reservation> addReservation(@RequestBody ReservationRequest request) {
65-
request.validateAndSetTimeId(jdbcTemplate);
66-
67-
// 예약 추가
68-
String sql = "INSERT INTO reservation (name, date, time_id) VALUES (?, ?, ?)";
69-
KeyHolder keyHolder = new GeneratedKeyHolder();
70-
71-
jdbcTemplate.update(connection -> {
72-
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
73-
ps.setString(1, request.getName());
74-
ps.setString(2, request.getDate());
75-
ps.setLong(3, request.getTimeId());
76-
return ps;
77-
}, keyHolder);
78-
79-
Long id = keyHolder.getKey().longValue();
80-
81-
String timeQuery = "SELECT time FROM time WHERE id = ?";
82-
String timeValue = jdbcTemplate.queryForObject(timeQuery, String.class, request.getTime());
83-
84-
Reservation newReservation = new Reservation(id, request.getName(), request.getDate(),
85-
new Time(request.getTimeId(), timeValue));
86-
87-
88-
return ResponseEntity.created(URI.create("/reservations/" + id)).body(newReservation);
40+
Reservation newReservation = reservationService.addReservation(request);
41+
return ResponseEntity.created(URI.create("/reservations/" + newReservation.getId())).body(newReservation);
8942
}
9043

9144
// 예약 삭제
9245
@DeleteMapping("/reservations/{id}")
9346
public ResponseEntity<Void> deleteReservation(@PathVariable Long id) {
94-
String sql = "DELETE FROM reservation WHERE id = ?";
95-
int rowsAffected = jdbcTemplate.update(sql, id);
96-
97-
if (rowsAffected > 0) {
98-
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
99-
}
100-
101-
throw new NotFoundReservationException("삭제할 예약이 없습니다.");
47+
reservationService.deleteReservation(id);
48+
return ResponseEntity.noContent().build();
10249
}
10350
}
Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,23 @@
11
package roomescape.controller;
22

3-
import org.springframework.http.HttpHeaders;
4-
import org.springframework.http.HttpStatus;
53
import org.springframework.http.ResponseEntity;
6-
import org.springframework.jdbc.core.JdbcTemplate;
7-
import org.springframework.jdbc.core.RowMapper;
8-
import org.springframework.jdbc.support.GeneratedKeyHolder;
9-
import org.springframework.jdbc.support.KeyHolder;
104
import org.springframework.stereotype.Controller;
115
import org.springframework.web.bind.annotation.*;
126
import roomescape.model.Time;
7+
import roomescape.service.TimeService;
138

149
import java.net.URI;
15-
import java.sql.PreparedStatement;
1610
import java.util.List;
1711

1812
@Controller
1913
public class TimeController {
2014

21-
private final JdbcTemplate jdbcTemplate;
15+
private final TimeService timeService;
2216

23-
public TimeController(JdbcTemplate jdbcTemplate) {
24-
this.jdbcTemplate = jdbcTemplate;
17+
public TimeController(TimeService timeService) {
18+
this.timeService = timeService;
2519
}
2620

27-
private final RowMapper<Time> timeRowMapper = (rs, rowNum) -> new Time(
28-
rs.getLong("id"),
29-
rs.getString("time")
30-
);
31-
3221
// 시간 관리 페이지
3322
@GetMapping("/time")
3423
public String reservationPage() {
@@ -39,39 +28,23 @@ public String reservationPage() {
3928
@GetMapping("/times")
4029
@ResponseBody
4130
public ResponseEntity<List<Time>> getTimes() {
42-
String sql = "SELECT id, time FROM time";
43-
List<Time> times = jdbcTemplate.query(sql, timeRowMapper);
31+
List<Time> times = timeService.getAllTimes();
4432
return ResponseEntity.ok(times);
4533
}
4634

4735
// 시간 추가
4836
@PostMapping("/times")
37+
@ResponseBody
4938
public ResponseEntity<Time> addTime(@RequestBody Time request) {
50-
String sql = "INSERT INTO time (time) VALUES (?)";
51-
KeyHolder keyHolder = new GeneratedKeyHolder();
52-
53-
jdbcTemplate.update(connection -> {
54-
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
55-
ps.setString(1, request.getTime());
56-
return ps;
57-
}, keyHolder);
58-
59-
Long id = keyHolder.getKey().longValue();
60-
Time newTime = new Time(id, request.getTime());
61-
62-
return ResponseEntity.created(URI.create("/times/" + id)).body(newTime);
39+
Time newTime = timeService.addTime(request);
40+
return ResponseEntity.created(URI.create("/times/" + newTime.getId())).body(newTime);
6341
}
6442

6543
// 시간 삭제
6644
@DeleteMapping("/times/{id}")
45+
@ResponseBody
6746
public ResponseEntity<Void> deleteTime(@PathVariable Long id) {
68-
String sql = "DELETE FROM time WHERE id = ?";
69-
int rowsAffected = jdbcTemplate.update(sql, id);
70-
71-
if (rowsAffected > 0) {
72-
return ResponseEntity.noContent().build();
73-
}
74-
75-
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
47+
timeService.deleteTime(id);
48+
return ResponseEntity.noContent().build();
7649
}
7750
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package roomescape.dao;
2+
3+
import org.springframework.jdbc.core.JdbcTemplate;
4+
import org.springframework.jdbc.core.RowMapper;
5+
import org.springframework.jdbc.support.GeneratedKeyHolder;
6+
import org.springframework.jdbc.support.KeyHolder;
7+
import org.springframework.stereotype.Repository;
8+
import roomescape.model.Reservation;
9+
import roomescape.model.ReservationRequest;
10+
import roomescape.model.Time;
11+
12+
import java.sql.PreparedStatement;
13+
import java.util.List;
14+
15+
@Repository
16+
public class ReservationDao {
17+
18+
private final JdbcTemplate jdbcTemplate;
19+
20+
private final RowMapper<Reservation> reservationRowMapper = (rs, rowNum) -> new Reservation(
21+
rs.getLong("reservation_id"),
22+
rs.getString("name"),
23+
rs.getString("date"),
24+
new Time(rs.getLong("time_id"), rs.getString("time_value"))
25+
);
26+
27+
public ReservationDao(JdbcTemplate jdbcTemplate) {
28+
this.jdbcTemplate = jdbcTemplate;
29+
}
30+
31+
public JdbcTemplate getJdbcTemplate() {
32+
return jdbcTemplate;
33+
}
34+
35+
public List<Reservation> findAll() {
36+
String sql = """
37+
SELECT
38+
r.id as reservation_id,
39+
r.name,
40+
r.date,
41+
t.id as time_id,
42+
t.time as time_value
43+
FROM reservation as r
44+
INNER JOIN time as t
45+
ON r.time_id = t.id
46+
""";
47+
return jdbcTemplate.query(sql, reservationRowMapper);
48+
}
49+
50+
public Reservation save(ReservationRequest request) {
51+
String sql = "INSERT INTO reservation (name, date, time_id) VALUES (?, ?, ?)";
52+
KeyHolder keyHolder = new GeneratedKeyHolder();
53+
54+
jdbcTemplate.update(connection -> {
55+
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
56+
ps.setString(1, request.getName());
57+
ps.setString(2, request.getDate());
58+
ps.setLong(3, request.getTimeId());
59+
return ps;
60+
}, keyHolder);
61+
62+
Long id = keyHolder.getKey().longValue();
63+
64+
String timeQuery = "SELECT time FROM time WHERE id = ?";
65+
String timeValue = jdbcTemplate.queryForObject(timeQuery, String.class, request.getTimeId());
66+
67+
return new Reservation(id, request.getName(), request.getDate(), new Time(request.getTimeId(), timeValue));
68+
}
69+
70+
public int deleteById(Long id) {
71+
String sql = "DELETE FROM reservation WHERE id = ?";
72+
return jdbcTemplate.update(sql, id);
73+
}
74+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package roomescape.dao;
2+
3+
import org.springframework.jdbc.core.JdbcTemplate;
4+
import org.springframework.jdbc.core.RowMapper;
5+
import org.springframework.jdbc.support.GeneratedKeyHolder;
6+
import org.springframework.jdbc.support.KeyHolder;
7+
import org.springframework.stereotype.Repository;
8+
import roomescape.model.Time;
9+
10+
import java.sql.PreparedStatement;
11+
import java.util.List;
12+
13+
@Repository
14+
public class TimeDao {
15+
16+
private final JdbcTemplate jdbcTemplate;
17+
18+
private final RowMapper<Time> timeRowMapper = (rs, rowNum) -> new Time(
19+
rs.getLong("id"),
20+
rs.getString("time")
21+
);
22+
23+
public TimeDao(JdbcTemplate jdbcTemplate) {
24+
this.jdbcTemplate = jdbcTemplate;
25+
}
26+
27+
public List<Time> findAll() {
28+
String sql = "SELECT id, time FROM time";
29+
return jdbcTemplate.query(sql, timeRowMapper);
30+
}
31+
32+
public Time save(Time time) {
33+
String sql = "INSERT INTO time (time) VALUES (?)";
34+
KeyHolder keyHolder = new GeneratedKeyHolder();
35+
36+
jdbcTemplate.update(connection -> {
37+
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
38+
ps.setString(1, time.getTime());
39+
return ps;
40+
}, keyHolder);
41+
42+
Long id = keyHolder.getKey().longValue();
43+
return new Time(id, time.getTime());
44+
}
45+
46+
public int deleteById(Long id) {
47+
String sql = "DELETE FROM time WHERE id = ?";
48+
return jdbcTemplate.update(sql, id);
49+
}
50+
}

src/main/java/roomescape/exception/GlobalExceptionHandler.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
public class GlobalExceptionHandler {
1212

1313
// 특정 예외를 처리하는 메서드를 정의
14+
1415
@ExceptionHandler(NotFoundReservationException.class)
1516
public ResponseEntity<String> handleNotFoundReservationException(NotFoundReservationException e) {
1617
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
@@ -20,4 +21,9 @@ public ResponseEntity<String> handleNotFoundReservationException(NotFoundReserva
2021
public ResponseEntity<String> handleInvalidReservationException(InvalidReservationException e) {
2122
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
2223
}
24+
25+
@ExceptionHandler(IllegalArgumentException.class)
26+
public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException e) {
27+
return ResponseEntity.badRequest().body(e.getMessage());
28+
}
2329
}

src/main/java/roomescape/model/Time.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public String getTime() {
2525
}
2626

2727
public void setTime(String time) {
28+
if (time == null || time.trim().isEmpty()) {
29+
throw new IllegalArgumentException("시간 값이 비어 있습니다.");
30+
}
2831
this.time = time;
2932
}
3033
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package roomescape.service;
2+
3+
import org.springframework.stereotype.Service;
4+
import roomescape.dao.ReservationDao;
5+
import roomescape.exception.NotFoundReservationException;
6+
import roomescape.model.Reservation;
7+
import roomescape.model.ReservationRequest;
8+
9+
import java.util.List;
10+
11+
@Service
12+
public class ReservationService {
13+
14+
private final ReservationDao reservationDao;
15+
16+
public ReservationService(ReservationDao reservationDao) {
17+
this.reservationDao = reservationDao;
18+
}
19+
20+
public List<Reservation> getReservations() {
21+
return reservationDao.findAll();
22+
}
23+
24+
public Reservation addReservation(ReservationRequest request) {
25+
request.validateAndSetTimeId(reservationDao.getJdbcTemplate());
26+
return reservationDao.save(request);
27+
}
28+
29+
public void deleteReservation(Long id) {
30+
int rowsAffected = reservationDao.deleteById(id);
31+
if (rowsAffected == 0) {
32+
throw new NotFoundReservationException("삭제할 예약이 없습니다.");
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)