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] 남해윤 미션 제출합니다. #391

Open
wants to merge 19 commits into
base: haeyoon1
Choose a base branch
from

Conversation

haeyoon1
Copy link

안녕하세요 원태연 리뷰어님! 리뷰 잘 부탁 드립니다!
지난주에 다른 리뷰어님께서 time의 자료형을 String이 아니라 LocalTime으로 변경해보라는 리뷰를 남겨주셔서 그렇게 변경해 보았는데 이번주 미션에서 오류가 너무 많이 나더라고요 .. 원래 조건대로 String형태로 지정하는 것이 나을까요?

그리고 최대한 코드를 수정해보았는데 9단계 미션부터 오류가 나서 실행되지 않습니다.... 추가로 더 수정해서 다시 pr올리도록 하겠습니다 ㅠㅠ 또한 어느부분이 잘못됐는지 궁금합니다. 늦게 제출하여 죄송합니다. 리뷰 잘 부탁드립니다! 감사합니다.

- Gradle 수정
- HomeController, ReservationController 생성
- Reservation dto 생성
- ReservationController속 변수에 값 넣어준 코드 주석처리
- h2 데이터베이스를 활용하여 데이터를 저장하도록 수정
- 예약 조회 API 처리 로직에서 저장된 예약을 조회할 때 데이터베이스를 활용하도록 수정
- 예약 추가/취소 API 처리 로직에서 데이터베이스를 활용하도록 수정
- time 관련 controller, dao, dto, entity, repository, service 추가
-reservation time의 문자형을 Time형으로 수정
- 테이블 스키마 재정의
- 예약 클래스 시간 타입 Time으로 수정
- 예약 쿼리 수정
@haeyoon1 haeyoon1 changed the base branch from main to haeyoon1 November 29, 2024 06:04
Copy link

@TaeyeonRoyce TaeyeonRoyce left a comment

Choose a reason for hiding this comment

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

안녕하세요, 해윤님!
미션 하시느라 수고 많으셨습니다.

Repository와 Dao, controller, service로 계층화가 잘 되어있는 것 같아요.
몇가지 코멘트 남겼으니 확인해주세요!
추가로 깨지는 테스트도 같이 수정 하신 후 실행 가능한 상태로 전달주세요!


질문에 대한 답변

원래 조건대로 String형태로 지정하는 것이 나을까요?

이 부분에 대해 고민이 남아있는 코드 같아요.
시간 정보를 String이 아닌 시간 관련 객체로 변환하는 작업이 묻어 있더군요.

꼭 시간 정보를 LocalTime, LocalDateTime으로 저장할 의무는 없습니다. 이것 역시 선택의 영역이에요.

Java에서는 String 대신 LocalDateTime과 같은 타입을, DB에서는 VARCHAR 대신 TimeStamp 혹은 datetime과 같은 시간 정보를 위한 타입을 제공 하는데요.
이러한 타입은 시간들 사이에 연산(날짜 추가 등)을 제공하기도 하고, Timezone으로 세계시간을 반영 할 수도 있고, 해당 정보에서 년도, 달, 일을 추출 하는 등 날짜에 특화된 다양한 기능들을 제공합니다.
이런 기능이 필요하다면 직접 만들어서 사용 하기 보단 해당 타입을 사용 하는게 낫겠죠.

그리고 제 경험상, 시간 정보를 다루는 경우에는 거의 모든 상황에서 해당 타입을 사용하는게 String타입 을 유지하는 것보다 유용합니다.

해당 타입들이 어떤 기능들을 제공하는지 찾아보시고, 익숙해지면 매우 도움 될겁니다!
그래서 저는 시간 정보에 대해 String 타입보단 LocalDateTime이나 LocalTime 과 같은 타입으로 사용하는 것을 권장드려요!

그러면, 어느 계층에서 해당 타입을 사용할 지, 언제 변환할 지 고민 하셔야 합니다.
저는 ui 계층에선 String, presentation -> application으로 전달할 때 변환 할 것 같아요.
반대로 응답을 만드는 상황에서도 application -> presentation로 응답할 때 변환하고요.
이유는, 아시다시피 날짜/시간 형식이 너무나도 다양하게 있습니다. ex) "07:09", "7:09", "07-09" presentation` 영역에서는 각 클라이언트 마다 형식을 받고, application에서 사용 될 수 있도록 변환하는 거죠.

"07:09", "7:09", "07-09" 처럼 다양한 형식에 대해서도 application에서 정의한 time 객체로만 변환 하여 전달 한다면 형식에 상관없이 로직을 수행 할 수 있죠.

그리고, database에 저장할 때(persistence) 역시 DB에 정의 된 타입으로 전달 할 수 있습니다.
DB에서 VARCHAR를 사용하고 있다면, Time -> String 으로의 변환이 필요할 테고,
아니면 DB에서 TimeStamp 타입으로 정의하면 그대로 저장하면 됩니다!
jdbcTemplate에서 timestamp로 저장하는 방식을 간단하게 정리한 글 공유드릴게요. 참고하시면 도움 될 것 같습니다.

조금 작업이 들 수 있지만, 시간 데이터에 대해서 String 대신 제공 되는 시간 관련 객체를 사용하시면 학습에도, 앞으로의 개발에도 도움이 될 것 같습니다!

Comment on lines +18 to +19
@Controller
public class TimeController {

Choose a reason for hiding this comment

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

Controller는 전체적으로 깔끔하네요!👍👍

Comment on lines 42 to 43
String query = "SELECT id FROM reservation ORDER BY id DESC LIMIT 1";
Long id = jdbcTemplate.queryForObject(query, Long.class);

Choose a reason for hiding this comment

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

방금 저장된 저장한 예약의 id를 조회하는 것 같아요.
이 방식은 여러 저장이 이루어지는 환경에서 문제가 생길 수 있어요.

저장과 동시에 DB에서 생성된 id를 반환하는 방식을 활용해보세요!

  • jdbcTemplate에서는 KeyHolder를 사용해볼 수 있어요

Comment on lines 26 to 33
String sql = "INSERT INTO time(time) VALUES (?)";
jdbcTemplate.update(sql, time.getTime());

String query = "SELECT id FROM time ORDER BY id DESC LIMIT 1";
Long id = jdbcTemplate.queryForObject(query, Long.class);

return new Time(id, time.getTime());
}

Choose a reason for hiding this comment

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

방금 저장한 시간의 id를 조회하는 것 같아요.
이 방식은 여러 저장이 이루어지는 환경에서 문제가 생길 수 있습니다.

27번 라인 이후 30번 라인의 실행 되지 전에 다른 쓰레드에서 저장이 이루어졌다면...?

저장과 동시에 DB에서 생성된 id를 반환하는 방식을 활용해보세요!

  • jdbcTemplate에서는 KeyHolder를 사용해볼 수 있어요

return time;
}

public LocalTime getTimeASALocalTime(){ //string->LocalTime

Choose a reason for hiding this comment

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

메서드 네이밍 컨벤션에 맞춰주세요!

Suggested change
public LocalTime getTimeASALocalTime(){ //string->LocalTime
public LocalTime getTimeAsLocalTime(){ //string->LocalTime

Comment on lines 33 to 37
Reservation reservation = new Reservation(
requestDto.getName(),
requestDto.getDate(),
requestDto.getTime()
requestDto.getStringTimeAsTime()
);

Choose a reason for hiding this comment

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

Dto -> Entity로의 변환 작업을 dto에 편의 메서드를 추가해볼 수도 있을 것 같아요.

class ReservationRequestDto {
// ...

    public Reservation toReservation() {
         // 변환 로직
    }
}

Dto 객체에 변환 로직을 추가하여 getStringTimeAsTime() 메서드를 굳이 제공하지 않아도 될거 같네요!

Copy link
Author

@haeyoon1 haeyoon1 Dec 19, 2024

Choose a reason for hiding this comment

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

ReservationService 클래스의 createReservation 메서드에

        Long timeId = parseTimeId(requestDto.getTime());
        Time time = findTimeById(timeId);

        Reservation reservation = new Reservation(
                requestDto.getName(),
                requestDto.getDate(),
                time
        );

이렇게 수정했는데 처음에 코멘트 남겨주신대로 dto에 변환 로직을 만들어서 작성하는 것이 나을까요?

.map(time -> new TimeResponseDto(
time.getId(),
time.getTimeASALocalTime()))
.collect(Collectors.toList());

Choose a reason for hiding this comment

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

아래처럼 변경할 수 있어요.

Suggested change
.collect(Collectors.toList());
.toList();

약간의 차이점이 있으니 알고계시면 좋습니다!

id BIGINT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
date VARCHAR(255) NOT NULL,
time_id BIGINT, // TODO: 수정

Choose a reason for hiding this comment

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

Sql의 주석은 --로 표기해요.
잘못된 주석 표기로 Sql 문법 오류가 나서 테스트 실행이 안되고 있어요ㅠ

Suggested change
time_id BIGINT, // TODO: 수정
time_id BIGINT, -- TODO: 수정

# Conflicts:
#	src/main/java/roomescape/dao/ReservationDao.java
#	src/main/java/roomescape/dto/ReservationRequestDto.java
#	src/main/java/roomescape/entity/Reservation.java
#	src/main/java/roomescape/entity/Time.java
#	src/main/java/roomescape/repository/ReservationRepository.java
#	src/main/java/roomescape/service/ReservationService.java
#	src/main/java/roomescape/service/TimeService.java
@haeyoon1
Copy link
Author

리뷰어님 피드백 받아 수정하였습니다! 혜빈님이 Reservation 엔티티에 Time 객체가 Localtime을 import하고있지 제가 만든 time 클래스를 가르키고 있지 않은 것 같다고 하셔서 해당 방법대로 수정하고 많이 시도 해보았으나 ... 여전히 아직 9단계는 해결하지 못하였습니다 ㅠㅠㅠㅠ 혹시 수정이 필요한 부분있다면 말씀해주세요! 또한 틀린부분 이외에도 다양한 피드백 부탁드립니다! 감사합니다:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants