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

[FEAT] Concert 조회, 삽입, 삭제 구현 #14

Merged
merged 3 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.book_your_seat.concert;

public final class ConcertConst {

public static final String NO_DATA_IN_REPOSITORY = "일치하는 아이디가 없습니다!";
public static final int TOTAL_STOCK = 100;

private ConcertConst() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.example.book_your_seat.concert.controller;

import com.example.book_your_seat.concert.controller.dto.AddConcertRequest;
import com.example.book_your_seat.concert.controller.dto.ConcertResponse;
import com.example.book_your_seat.concert.service.ConcertCommandService;
import com.example.book_your_seat.concert.service.ConcertQueryService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RequiredArgsConstructor
@RequestMapping("/concerts")
@RestController
public class ConcertController {

private final ConcertCommandService concertCommandService;
private final ConcertQueryService concertQueryService;

@GetMapping
public ResponseEntity<List<ConcertResponse>> findAll() {
List<ConcertResponse> responses = concertQueryService.findAll();
return ResponseEntity.ok(responses);
}

@GetMapping("/{concertId}")
public ResponseEntity<ConcertResponse> findById(@PathVariable final Long concertId) {
ConcertResponse response = concertQueryService.findById(concertId);
return ResponseEntity.ok(response);
}

@PostMapping
public ResponseEntity<ConcertResponse> addConcert(
@Valid @RequestBody final AddConcertRequest request
) {
ConcertResponse response = concertCommandService.add(request);
return ResponseEntity.status(HttpStatus.CREATED).body(response);
}

@DeleteMapping("/{concertId}")
public ResponseEntity<Void> deleteById(@PathVariable final Long concertId) {
concertCommandService.delete(concertId);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.example.book_your_seat.concert.controller.dto;

import com.example.book_your_seat.concert.domain.Concert;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;


import java.time.LocalDate;

import static com.example.book_your_seat.concert.ConcertConst.TOTAL_STOCK;

public record AddConcertRequest(

@NotBlank
String title,

@NotNull
LocalDate startDate,

@NotNull
LocalDate endDate,

@NotNull
Integer price,

@NotNull
Integer time
) {
kcsc2217 marked this conversation as resolved.
Show resolved Hide resolved
public static Concert to(final AddConcertRequest request) {
return new Concert(request.title, TOTAL_STOCK,
kwanse marked this conversation as resolved.
Show resolved Hide resolved
request.startDate, request.endDate, request.price, request.time);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.example.book_your_seat.concert.controller.dto;

import com.example.book_your_seat.concert.domain.Concert;

import com.example.book_your_seat.review.domain.Review;
import com.example.book_your_seat.seat.domain.Seat;
import lombok.Getter;

import java.time.LocalDate;
import java.util.List;

@Getter
public final class ConcertResponse {
private final Long id;
private final String title;
private final Integer totalStock;
private final LocalDate startDate;
private final LocalDate endDate;
private final Integer price;
private final Integer time;
private final List<Review> reviews;
private final List<Seat> seats;

private ConcertResponse(final Concert concert) {
this.id = concert.getId();
this.title = concert.getTitle();
this.totalStock = concert.getTotalStock();
this.startDate = concert.getStartDate();
this.endDate = concert.getEndDate();
this.price = concert.getPrice();
this.time = concert.getTime();
this.reviews = concert.getReviews();
this.seats = concert.getSeats();
}

public static ConcertResponse from(final Concert concert) {
return new ConcertResponse(concert);
}
kwanse marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
import jakarta.persistence.OneToMany;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.IntStream;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -28,18 +31,18 @@ public class Concert extends BaseEntity {
private Long id;

private String title;
private int totalStock;
private Integer totalStock;
kwanse marked this conversation as resolved.
Show resolved Hide resolved

private LocalDate startDate;
private LocalDate endDate;

private int price;
private Integer price;
private int time;

tnals2384 marked this conversation as resolved.
Show resolved Hide resolved
@OneToMany(mappedBy = "concert", cascade = CascadeType.ALL)
private final List<LikeConcert> likeConcerts = new ArrayList<>();

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@OneToMany(mappedBy = "concert", cascade = CascadeType.ALL)
private final List<Review> reviews = new ArrayList<>();

@OneToMany(mappedBy = "concert", cascade = CascadeType.ALL)
Expand All @@ -55,6 +58,12 @@ public Concert(String title, int totalStock, LocalDate startDate, LocalDate endD
this.endDate = endDate;
this.price = price;
this.time = time;
initializeSeats(); // 혹시라도 Seat 가 100개를 초과하지 않을까
}

private void initializeSeats() {
IntStream.range(0, 100)
.forEach(i -> new Seat(this));
}
kwanse marked this conversation as resolved.
Show resolved Hide resolved

public void addLikeConcert(LikeConcert likeConcert) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.example.book_your_seat.concert.domain.Concert;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
Copy link
Collaborator

@AnTaeho AnTaeho Sep 24, 2024

Choose a reason for hiding this comment

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

P4
제가 알기로 JPARepository를 상속 받으면 @repository가 필요 없는 것으로 알고 있는데
리포지토리라는 것을 명시해주기 위해서 작성하신건가요?
그렇다면 저는 있어도 좋다고 생각합니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

제가 알기로 JPARepository를 상속 받으면 @repository가 필요 없는 것으로 알고 있는데 리포지토리라는 것을 명시해주기 위해서 작성하신건가요? 그렇다면 저는 있어도 좋다고 생각합니다!

그냥 이름표 같은 느낌으로 줘봤습니당..!

public interface ConcertRepository extends JpaRepository<Concert, Long> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.example.book_your_seat.concert.domain.LikeConcert;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface LikeConcertRepository extends JpaRepository<LikeConcert, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.book_your_seat.concert.service;

import com.example.book_your_seat.concert.controller.dto.AddConcertRequest;
import com.example.book_your_seat.concert.controller.dto.ConcertResponse;

public interface ConcertCommandService {

ConcertResponse add(AddConcertRequest request);
void delete(Long id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.example.book_your_seat.concert.service;


import com.example.book_your_seat.concert.domain.Concert;
import com.example.book_your_seat.concert.controller.dto.AddConcertRequest;
import com.example.book_your_seat.concert.controller.dto.ConcertResponse;
import com.example.book_your_seat.concert.repository.ConcertRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@RequiredArgsConstructor
@Service
public class ConcertCommandServiceImpl implements ConcertCommandService {

private final ConcertRepository concertRepository;

@Override
public ConcertResponse add(final AddConcertRequest request) {
Concert concert = AddConcertRequest.to(request);
Concert savedConcert = concertRepository.save(concert);
return ConcertResponse.from(savedConcert);
}

@Override
public void delete(final Long id) {
concertRepository.deleteById(id);
kwanse marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.book_your_seat.concert.service;

import com.example.book_your_seat.concert.controller.dto.ConcertResponse;

import java.util.List;

public interface ConcertQueryService {

List<ConcertResponse> findAll();
ConcertResponse findById(Long id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.example.book_your_seat.concert.service;

import com.example.book_your_seat.concert.controller.dto.ConcertResponse;
import com.example.book_your_seat.concert.repository.ConcertRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static com.example.book_your_seat.concert.ConcertConst.NO_DATA_IN_REPOSITORY;

@Transactional(readOnly = true)
@RequiredArgsConstructor
@Service
public class ConcertQueryServiceImpl implements ConcertQueryService {

private final ConcertRepository concertRepository;

@Override
public List<ConcertResponse> findAll() {
return concertRepository.findAll().stream()
.map(ConcertResponse::from)
.toList();
}

@Override
public ConcertResponse findById(final Long id) {
return concertRepository.findById(id)
.map(ConcertResponse::from)
.orElseThrow(() -> new IllegalArgumentException(NO_DATA_IN_REPOSITORY));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.book_your_seat;

import com.example.book_your_seat.concert.controller.ConcertController;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(controllers = {
ConcertController.class
})
public abstract class ControllerTestSupport {

@Autowired
protected MockMvc mockMvc;
@Autowired
protected ObjectMapper objectMapper;


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.book_your_seat;

import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public abstract class IntegerTestSupport {


}
Loading
Loading