Skip to content
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] 김이화 미션 제출합니다. #309

Open
wants to merge 14 commits into
base: ihwag719
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:rest-assured:5.3.1'
testImplementation 'org.assertj:assertj-core:3.20.2'
}

test {
Expand Down
75 changes: 19 additions & 56 deletions src/main/java/roomescape/controller/ReservationController.java
Original file line number Diff line number Diff line change
@@ -1,77 +1,40 @@
package roomescape.controller;

import org.springframework.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;
import roomescape.exception.InvalidReservationException;
import roomescape.exception.NotFoundReservationException;
import roomescape.model.Reservation;
import roomescape.dto.ReservationRequestDto;
import roomescape.dto.ReservationResponseDto;
import roomescape.service.ReservationService;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

@Controller
@RestController
@RequestMapping("/reservations")
public class ReservationController {

private List<Reservation> reservations = new ArrayList<>();
private final ReservationService reservationService;

private AtomicLong index = new AtomicLong(1);

@GetMapping("/reservation")
public String reservation() {
return "reservation";
@Autowired
public ReservationController(ReservationService reservationService) {
this.reservationService = reservationService;
}

@GetMapping("/reservations")
@ResponseBody
public List<Reservation> getReservations() {
return reservations;
@GetMapping
public List<ReservationResponseDto> getReservations() {
return reservationService.getAllReservations();
}

@PostMapping("/reservations")
@ResponseBody
public ResponseEntity<Reservation> createReservation(@RequestBody Reservation reservation) {
validateReservation(reservation);

Long id = index.getAndIncrement();
String name = reservation.getName();
String date = reservation.getDate();
String time = reservation.getTime();

Reservation newReservation = new Reservation(id, name, date, time);
reservations.add(newReservation);

return ResponseEntity.created(URI.create("/reservations/" + newReservation.getId())).body(newReservation);
@PostMapping
public ResponseEntity<ReservationResponseDto> createReservation(@RequestBody ReservationRequestDto requestDto) {
ReservationResponseDto responseDto = reservationService.createReservation(requestDto);
return ResponseEntity.created(URI.create("/reservations/" + responseDto.getId())).body(responseDto);
}

@DeleteMapping("/reservations/{id}")
@ResponseBody
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteReservation(@PathVariable Long id) {
boolean removed = reservations.removeIf(r -> r.getId() == id);
if (!removed) {
throw new NotFoundReservationException("예약을 찾을 수 없습니다: " + id);
}
reservationService.deleteReservation(id);
return ResponseEntity.noContent().build();
}

@ExceptionHandler({InvalidReservationException.class, NotFoundReservationException.class})
public ResponseEntity<String> handleException(RuntimeException e, WebRequest request) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}

private void validateReservation(Reservation reservation) {
if (reservation.getName() == null || reservation.getName().isEmpty()) {
throw new InvalidReservationException("이름이 필요합니다.");
}
if (reservation.getDate() == null || reservation.getDate().isEmpty()) {
throw new InvalidReservationException("날짜가 필요합니다.");
}
if (reservation.getTime() == null || reservation.getTime().isEmpty()) {
throw new InvalidReservationException("시간이 필요합니다");
}
}
}
40 changes: 40 additions & 0 deletions src/main/java/roomescape/controller/TimeController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package roomescape.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import roomescape.dto.TimeRequestDto;
import roomescape.dto.TimeResponseDto;
import roomescape.service.TimeService;

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

@RestController
@RequestMapping("/times")
public class TimeController {

private final TimeService timeService;

@Autowired
public TimeController(TimeService timeService) {
this.timeService = timeService;
}

@GetMapping
public List<TimeResponseDto> getTimes() {
return timeService.getAllTimes();
}

@PostMapping
public ResponseEntity<TimeResponseDto> createTime(@RequestBody TimeRequestDto timeRequestDto) {
TimeResponseDto newTimeDto = timeService.createTime(timeRequestDto);
return ResponseEntity.created(URI.create("/times/" + newTimeDto.getId())).body(newTimeDto);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteTime(@PathVariable Long id) {
timeService.deleteTime(id);
return ResponseEntity.noContent().build();
}
}
14 changes: 14 additions & 0 deletions src/main/java/roomescape/controller/ViewController.java

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

시간 관리 페이지 Mapping도 있어야 하지 않나용? 없어도 시간 관리 페이지가 나오는지 궁금합니당

Copy link
Author

@ihwag719 ihwag719 Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Viewcontroller에 시간 관리 페이지를 작성하지 않아서 추가했습니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package roomescape.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/reservations")
public class ViewController {
@GetMapping("/reservationpage")
public String reservationPage() {
return "new-reservation";
}
}
81 changes: 81 additions & 0 deletions src/main/java/roomescape/dao/ReservationDAO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package roomescape.dao;

import org.springframework.beans.factory.annotation.Autowired;
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.exception.NotFoundReservationException;
import roomescape.domain.Reservation;
import roomescape.domain.Time;

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

@Repository
public class ReservationDAO {

private JdbcTemplate jdbcTemplate;

@Autowired
public ReservationDAO(JdbcTemplate jdbcTemplate, TimeDAO timeDAO) {
this.jdbcTemplate = jdbcTemplate;
}

private final RowMapper<Reservation> rowMapper = (resultSet, rowNum) -> {
Time time = new Time(
resultSet.getLong("time_id"),
resultSet.getString("time_value")
);
return new Reservation(
resultSet.getLong("reservation_id"),
resultSet.getString("name"),
resultSet.getString("date"),
time
);
};

public List<Reservation> findAllReservations() {
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);
}

public Reservation insert(Reservation reservation) {
Time time = reservation.getTime();
KeyHolder keyHolder = new GeneratedKeyHolder();

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

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

jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(
"INSERT INTO reservation(name, date, time_id) VALUES (?, ?, ?)", new String[]{"id"});
ps.setString(1, reservation.getName());
ps.setString(2, reservation.getDate());
ps.setLong(3, timeId);
return ps;
}, keyHolder);

Long reservationId = keyHolder.getKey().longValue();
return new Reservation(reservationId, reservation.getName(), reservation.getDate(), new Time(timeId, time.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;
}
}
65 changes: 65 additions & 0 deletions src/main/java/roomescape/dao/TimeDAO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package roomescape.dao;

import org.springframework.beans.factory.annotation.Autowired;
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.domain.Time;

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

@Repository
public class TimeDAO {

private JdbcTemplate jdbcTemplate;

@Autowired
public TimeDAO(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

private final RowMapper<Time> rowMapper = (resultSet, rowNum) -> {
Time time = new Time(
resultSet.getLong("id"),
resultSet.getString("time"));
return time;
};

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

public Time findByTimeValue(String timeValue) {
String sql = "SELECT id, time FROM time where time = ?";
try {
return jdbcTemplate.queryForObject(sql, rowMapper, timeValue);
} catch (EmptyResultDataAccessException e) {
return null;
}
}

public Time insert(Time time) {

KeyHolder keyHolder = new GeneratedKeyHolder();

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

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

public void delete(Long id) {
String sql = "DELETE FROM time WHERE id = ?";
jdbcTemplate.update(sql, id);
}
}
32 changes: 32 additions & 0 deletions src/main/java/roomescape/domain/Reservation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package roomescape.domain;

public class Reservation {
private Long id;
private String name;
private String date;
private Time time;

public Reservation(Long id, String name, String date, Time 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 Time getTime() {
return time;
}

}
19 changes: 19 additions & 0 deletions src/main/java/roomescape/domain/Time.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package roomescape.domain;

public class Time {
private Long id;
private String time;

public Time(Long id, String time) {
this.id = id;
this.time = time;
}

public Long getId() {
return id;
}

public String getTime() {
return time;
}
}
25 changes: 25 additions & 0 deletions src/main/java/roomescape/dto/ReservationRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package roomescape.dto;

public class ReservationRequestDto {
private String name;
private String date;
private String time;

public ReservationRequestDto(String name, String date, String time) {
this.name = name;
this.date = date;
this.time = time;
}

public String getName() {
return name;
}

public String getDate() {
return date;
}

public String getTime() {
return time;
}
}
Loading