Skip to content

Commit

Permalink
feat: Concert 조회, 삽입, 삭제 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
김관현 authored and 김관현 committed Sep 24, 2024
1 parent d4ebefc commit 76f3896
Show file tree
Hide file tree
Showing 14 changed files with 393 additions and 3 deletions.
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
) {
public static Concert to(final AddConcertRequest request) {
return new Concert(request.title, TOTAL_STOCK,
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);
}
}
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;

private LocalDate startDate;
private LocalDate endDate;

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

@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));
}

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

0 comments on commit 76f3896

Please sign in to comment.