Skip to content
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
6 changes: 5 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

// jakarta.persistence-api 의존성 명시적 추가 (필요한 경우)
implementation 'jakarta.persistence:jakarta.persistence-api'


implementation 'dev.akkinoc.spring.boot:logback-access-spring-boot-starter:4.0.0'

Expand Down
23 changes: 11 additions & 12 deletions src/main/java/roomescape/auth/TokenInterceptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,18 @@ public TokenInterceptor(AuthService authService) {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Cookie[] cookies = request.getCookies();

if (cookies == null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
if (cookies != null) {
String token = Arrays.stream(cookies)
.filter(cookie -> "token".equals(cookie.getName()))
.map(Cookie::getValue)
.findFirst()
.orElse(null);

if (token != null && !token.isBlank()) {
LoginMember loginMember = authService.parseMemberInfo(token);
request.setAttribute("loginMember", loginMember);
}
}

String token = Arrays.stream(cookies)
.filter(cookie -> "token".equals(cookie.getName()))
.map(Cookie::getValue)
.findFirst()
.orElse(null);

LoginMember loginMember = authService.parseMemberInfo(token);
request.setAttribute("loginMember", loginMember);
return HandlerInterceptor.super.preHandle(request, response, handler);
}
}
21 changes: 21 additions & 0 deletions src/main/java/roomescape/member/Member.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
package roomescape.member;


import jakarta.persistence.*;

@Entity
public class Member {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "member_id", nullable = false)
private Long id;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private String email;

@Column(nullable = false)
private String password;

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private Role role;

public Member(Long id, String name, String email, Role role) {
Expand All @@ -21,6 +38,10 @@ public Member(String name, String email, String password, Role role) {
this.role = role;
}

public Member() {

}

public Long getId() {
return id;
}
Expand Down
13 changes: 0 additions & 13 deletions src/main/java/roomescape/member/MemberDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,4 @@ public Member findByEmailAndPassword(String email, String password) {
email, password
);
}

public Member findByName(String name) {
return jdbcTemplate.queryForObject(
"SELECT id, name, email, role FROM member WHERE name = ?",
(rs, rowNum) -> new Member(
rs.getLong("id"),
rs.getString("name"),
rs.getString("email"),
Role.valueOf(rs.getString("role"))
),
name
);
}
}
9 changes: 9 additions & 0 deletions src/main/java/roomescape/member/MemberRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package roomescape.member;

import org.springframework.data.repository.CrudRepository;

import java.util.Optional;

public interface MemberRepository extends CrudRepository<Member, Long> {
Copy link

Choose a reason for hiding this comment

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

오호, 많은 Repository 아류 인터페이스들이 있는데 Crud를 선택한 이유가 있을까요?

Copy link
Author

Choose a reason for hiding this comment

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

현재 상황에서는 페이징이나 정렬과 같은 기능이 필요하다 생각하지 않아, 기본적인 crud만 제공하는 인터페이스를 사용했습니다.

Optional<Member> findByEmailAndPassword(String email, String password);
}
10 changes: 6 additions & 4 deletions src/main/java/roomescape/member/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@

@Service
public class MemberService {
private final MemberDao memberDao;

public MemberService(final MemberDao memberDao) {
this.memberDao = memberDao;
private final MemberRepository memberRepository;

public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}

public MemberResponse createMember(MemberRequest memberRequest) {
Member member = memberDao.save(new Member(memberRequest.name(), memberRequest.email(), memberRequest.password(), Role.USER));
Member member = memberRepository.save(new Member(memberRequest.name(), memberRequest.email(), memberRequest.password(), Role.USER));

return new MemberResponse(member.getId(), member.getName(), member.getEmail());
}

Expand Down
38 changes: 38 additions & 0 deletions src/main/java/roomescape/reservation/MyReservationResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package roomescape.reservation;

public class MyReservationResponse {

private Long id;
private String theme;
private String date;
private String time;
private String status;

public MyReservationResponse(Long id, String theme, String date, String time, String status) {
this.id = id;
this.theme = theme;
this.date = date;
this.time = time;
this.status = status;
}

public Long getId() {
return id;
}

public String getTheme() {
return theme;
}

public String getDate() {
return date;
}

public String getTime() {
return time;
}

public String getStatus() {
return status;
}
}
54 changes: 46 additions & 8 deletions src/main/java/roomescape/reservation/Reservation.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,66 @@
package roomescape.reservation;

import jakarta.persistence.*;
import roomescape.member.Member;
import roomescape.theme.Theme;
import roomescape.time.Time;
import roomescape.time.ParticipationTime;

@Entity
public class Reservation {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "reservation_id", nullable = false)
private Long id;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private String date;
private Time time;

@ManyToOne
Copy link

Choose a reason for hiding this comment

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

ManyToOne 안의 옵션을 보면 fetch 라는 옵션이 있어요. 기본이 EAGER로 되어있는데요, EAGER와 LAZY의 차이가 뭘까요? 어떤 옵션을 선택하는게 좋을까요?

Copy link
Author

Choose a reason for hiding this comment

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

EAGER와 LAZY 의 차이는 언제 데이터를 언제 불러올 것인가의 시점 차이라고 생각합니다.

EAGER의 경우, JPA가 해당 엔티티를 조회할 때 연관 데이터를 즉시 로드하고, LAZY의 경우, 불필요한 데이터를 로딩하지 않고 실제 사용될 경우에 로딩합니다.

따라서 연관 데이터 전체가 반드시 사용되는 경우라면, 관련 데이터를 N번 쿼리하게 되는 N+1 문제를 방지하기 위해 즉시 로딩 전략을 사용하는게 좋을 것 같지만, 연관 데이터가 항상 사용되는 것이 아니라면 과도한 메모리 사용을 방지하기 위해 지연 로딩 전략을 사용하는게 좋을 것 같습니다.

@JoinColumn(name = "member_id")
private Member member;

@ManyToOne
@JoinColumn(name = "time_id")
private ParticipationTime participationTime;

@ManyToOne
@JoinColumn(name = "theme_id")
private Theme theme;

public Reservation(Long id, String name, String date, Time time, Theme theme) {
public Reservation(Long id, String name, String date, ParticipationTime participationTime, Theme theme, Member member) {
this.id = id;
this.name = name;
this.date = date;
this.time = time;
this.participationTime = participationTime;
this.theme = theme;
this.member = member;
}

public Reservation(Long id, String name, String date, ParticipationTime participationTime, Theme theme) {
this.id = id;
this.name = name;
this.date = date;
this.participationTime = participationTime;
this.theme = theme;
}

public Reservation(String name, String date, ParticipationTime participationTime, Theme theme) {
this.name = name;
this.date = date;
this.participationTime = participationTime;
this.theme = theme;
}

public Reservation(String name, String date, Time time, Theme theme) {
public Reservation(String name, String date, ParticipationTime participationTime, Theme theme, Member member) {
this.name = name;
this.date = date;
this.time = time;
this.participationTime = participationTime;
this.theme = theme;
this.member = member;
}

public Reservation() {
Expand All @@ -41,8 +79,8 @@ public String getDate() {
return date;
}

public Time getTime() {
return time;
public ParticipationTime getTime() {
return participationTime;
}

public Theme getTheme() {
Expand Down
11 changes: 9 additions & 2 deletions src/main/java/roomescape/reservation/ReservationController.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ public List<ReservationResponse> list() {
return reservationService.findAll();
}

@GetMapping("/reservations/mine")
public List<MyReservationResponse> myReservations(LoginMember loginMember) {
return reservationService.findMyReservation(loginMember);
}

@PostMapping("/reservations")
public ResponseEntity create(@RequestBody ReservationRequest reservationRequest, LoginMember loginMember) {

if (reservationRequest.getDate() == null
|| reservationRequest.getTheme() == null
|| reservationRequest.getTime() == null) {
|| reservationRequest.getThemeId() == null
|| reservationRequest.getTimeId() == null) {
return ResponseEntity.badRequest().build();
}

Expand All @@ -44,4 +49,6 @@ public ResponseEntity delete(@PathVariable Long id) {
reservationService.deleteById(id);
return ResponseEntity.noContent().build();
}


}
Loading