Skip to content

[Spring MVC + JDBC + Core] 최승훈 미션 제출합니다. #359

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

Open
wants to merge 9 commits into
base: sseung3424
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ repositories {

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'
}
Expand Down
80 changes: 80 additions & 0 deletions src/main/java/roomescape/Controller/ReservationController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package roomescape.Controller;

import java.net.URI;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import roomescape.DTO.ReservationRequest;
import roomescape.Domain.Reservation;
import roomescape.Domain.Time;
import roomescape.Exception.NotFoundReservationException;
import roomescape.Service.ReservationService;

@RestController
public class ReservationController {

private final ReservationService reservationService;

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

@PostMapping("/reservations")
public ResponseEntity<Reservation> create(@RequestBody ReservationRequest request) {

if (request.getName() == null || request.getName().isEmpty() ||
request.getDate() == null || request.getDate().isEmpty() ||
request.getTime() == null || request.getTime().isEmpty()) {
throw new NotFoundReservationException("Reservation not found");
}

Long timeId;
try {
timeId = Long.valueOf(request.getTime());
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid time format");
}

Time time = new Time(timeId, null);
Reservation reservation = new Reservation(null, request.getName(), request.getDate(), time);

Long id = reservationService.addReservationByKey(reservation);

Reservation savedReservation = reservationService.getReservationByID(id);

return ResponseEntity.created(URI.create("/reservations/" + savedReservation.getId()))
.body(savedReservation);
}

@GetMapping("/reservations")
public ResponseEntity<List<Reservation>> read() {
List<Reservation> reservations = reservationService.getAllReservations();

return ResponseEntity.ok().body(reservations);
}

@DeleteMapping("/reservations/{id}")
public ResponseEntity<Void> delete(@PathVariable long id) {

List<Reservation> reservations = reservationService.getReservationsByID(id);

if (reservations.isEmpty()) {
throw new NotFoundReservationException("Reservation not found");
}

reservationService.deleteReservationByID(id);

return ResponseEntity.noContent().build();
}

@ExceptionHandler(NotFoundReservationException.class)
public ResponseEntity<Void> handleException(NotFoundReservationException e) {
return ResponseEntity.badRequest().build();
}
}
71 changes: 71 additions & 0 deletions src/main/java/roomescape/Controller/TimeController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package roomescape.Controller;

import java.net.URI;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import roomescape.Domain.Time;
import roomescape.Exception.NotFoundTimeException;
import roomescape.Service.TimeService;

@RestController
public class TimeController {

private final TimeService timeService;

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

@PostMapping("/times")
public ResponseEntity<Time> create(@RequestBody Time time) {

if (time.getTime() == null) {
throw new NotFoundTimeException("Time not found");
}

// 시간 포맷 유효성 검사
if (!time.getTime().matches("^\\d{2}:\\d{2}$")) {
throw new NotFoundTimeException("Invalid time format");
}

Long id = timeService.addTimeByKey(time);

Time savedTime = timeService.getTimeByID(id);

return ResponseEntity.created(URI.create("/times/" + savedTime.getId()))
.body(savedTime);
}

@GetMapping("/times")
public ResponseEntity<List<Time>> read() {
List<Time> times = timeService.getAllTimes();

return ResponseEntity.ok().body(times);
}

@DeleteMapping("/times/{id}")
public ResponseEntity<Void> delete(@PathVariable long id) {

List<Time> times = timeService.getTimesByID(id);

if (times.isEmpty()) {
throw new NotFoundTimeException("Time not found");
}

timeService.deleteTimeByID(id);

return ResponseEntity.noContent().build();
}

@ExceptionHandler(NotFoundTimeException.class)
public ResponseEntity<Void> handleException(NotFoundTimeException e) {
return ResponseEntity.badRequest().build();
}
}
18 changes: 18 additions & 0 deletions src/main/java/roomescape/Controller/ViewController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package roomescape.Controller;

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

@Controller
public class ViewController {

@GetMapping("/")
public String home() {
return "home";
}

@GetMapping("/reservation")
public String reservation() {
return "new-reservation";
}
}
80 changes: 80 additions & 0 deletions src/main/java/roomescape/DAO/ReservationDAO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package roomescape.DAO;

import java.sql.PreparedStatement;
import java.util.List;
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.Reservation;
import roomescape.Domain.Time;

@Repository
public class ReservationDAO {

private final JdbcTemplate jdbcTemplate;

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

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

public Reservation findReservationByID(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 = ?";
return jdbcTemplate.queryForObject(
sql,
reservationRowMapper,
id
);
}

public List<Reservation> findReservationsByID(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 = ?";
return jdbcTemplate.query(
sql,
reservationRowMapper,
id);
}

public Long insertWithKeyHolder(Reservation reservation) {
KeyHolder keyHolder = new GeneratedKeyHolder();
String sql = "INSERT INTO reservation (name, date, time_id) VALUES (?, ?, ?)";
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(sql, new String[] {"id"});
ps.setString(1, reservation.getName());
ps.setString(2, reservation.getDate());
ps.setLong(3, reservation.getTime().getId());
return ps;
}, keyHolder);

return keyHolder.getKey().longValue();
}

public int delete(Long id) {
String sql = "delete from reservation where id = ?";
return jdbcTemplate.update(sql, Long.valueOf(id));
}

private final RowMapper<Reservation> reservationRowMapper = (resultSet, rowNum) -> {
return new Reservation(
resultSet.getLong("id"),
resultSet.getString("name"),
resultSet.getString("date"),
new Time(
resultSet.getLong("time_id"),
resultSet.getString("time_value")
)
);
};
}
68 changes: 68 additions & 0 deletions src/main/java/roomescape/DAO/TimeDAO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package roomescape.DAO;

import java.sql.PreparedStatement;
import java.util.List;
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;

@Repository
public class TimeDAO {

private final JdbcTemplate jdbcTemplate;

public TimeDAO(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<Time> findAllTimes() {
String sql = "SELECT * FROM time";
return jdbcTemplate.query(
sql,
timeRowMapper
);
}

public Time findTimeByID(Long id) {
String sql = "SELECT * FROM time WHERE id = ?";
return jdbcTemplate.queryForObject(
sql,
timeRowMapper,
id
);
}

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

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

return keyHolder.getKey().longValue();
}

public int delete(Long id) {
String sql = "delete from time where id = ?";
return jdbcTemplate.update(sql, Long.valueOf(id));
}

private final RowMapper<Time> timeRowMapper = (resultSet, rowNum) -> {
return new Time(
resultSet.getLong("id"),
resultSet.getString("time")
);
};
}
31 changes: 31 additions & 0 deletions src/main/java/roomescape/DTO/ReservationRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package roomescape.DTO;

public class ReservationRequest {
private String name;
private String date;
private String time; // Time as a string (from user)

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDate() {
return date;
}

public void setDate(String date) {
this.date = date;
}

public String getTime() {
return time;
}

public void setTime(String time) {
this.time = time;
}
}
Loading