인생 디벨로퍼

[1단계] Stadium Detail 본문

Project/Final Project - Sporting (매칭)

[1단계] Stadium Detail

뫄뫙뫄 2023. 5. 1. 19:40
728x90

Controller

  @GetMapping("/user/detail/{stadiumId}")
    public ResponseEntity<?> detail(@PathVariable Long stadiumId) {

        StadiumDetailDTO stadiumDetailDTO = stadiumService.detail(
                stadiumId);

        return ResponseEntity.ok().body(new ResponseDto<>().data(stadiumDetailDTO));
    }

Service

  public StadiumDetailDTO detail(Long stadiumId) {

        Stadium stadium = stadiumRepository.findById(stadiumId).orElseThrow(() -> {
            throw new Exception400("존재하지 않는 경기장입니다.");
        });

        StadiumDetailDTO stadiumDetailDTO = stadiumRepository.findByStadiumId2(stadiumId);
        stadiumDetailDTO.setFileInfo(fileInfoRepository.findStadiumById(stadium.getFileInfo().getId()));

        stadiumDetailDTO.setCategory(stadiumRepository.findCategoryByStadiumId(stadium.getCategory().getId()));

        stadiumDetailDTO.setStadiumCourt(stadiumCourtRepository.findStadiumCourtByStadiumId(stadiumId));

        System.out.println("테스트 : " + stadiumDetailDTO.getStadiumCourt().get(0).getId());

        return stadiumDetailDTO;
    }

Repository

public interface StadiumCustomRepository {

	StadiumDetailDTO findByStadiumId2(@Param("categoryId") Long categoryId);
    SportCategoryDTO findCategoryByStadiumId(@Param("stadiumId") Long stadiumId);
 }
public interface FileInfoCustomRepository {
    FileInfoResponseDTO findStadiumById(@Param("id") Long id);
}
@Transactional
@RequiredArgsConstructor
@Repository
public class FileInfoRepositoryImpl implements FileInfoCustomRepository {

    private final JPAQueryFactory jpaQueryFactory;

    @Override
    public FileInfoResponseDTO findStadiumById(Long id) {
        QFileInfo qFileInfo = QFileInfo.fileInfo;

        JPAQuery<FileInfoResponseDTO> query = jpaQueryFactory
                .select(new QFileInfoResponseDTO(qFileInfo.id, qFileInfo.type))
                .from(qFileInfo)
                .where(qFileInfo.fileInfo.id.eq(id));

        return query.fetchOne();
    }
}

 

@Repository
@RequiredArgsConstructor
@Transactional
public class StadiumRepositoryImpl implements StadiumCustomRepository {

        private final JPAQueryFactory jpaQueryFactory;
		@Override
        public List<CourtResponseDTO> findCourtsByStadiumId(Long stadiumId) {
                QStadiumCourt qStadiumCourt = QStadiumCourt.stadiumCourt;
                QProfileFile qFile = QProfileFile.profileFile;
                JPAQuery<CourtResponseDTO> query = jpaQueryFactory
                                .select(new QCourtResponseDTO(qStadiumCourt.id, qStadiumCourt.title,
                                                qStadiumCourt.content, qStadiumCourt.capacity,
                                                qStadiumCourt.courtPrice, qStadiumCourt.stadium.category.sport,
                                                new QCourtFileResponseDto(qFile.id, qFile.fileUrl)))
                                .from(qStadiumCourt)
                                .leftJoin(qFile).on(qStadiumCourt.fileInfo.id.eq(qFile.fileInfo.id))
                                .where(qStadiumCourt.stadium.id.eq(stadiumId));

                return query.fetch();
        }
		@Override
        public StadiumDetailDTO findByStadiumId2(Long id) {
                QStadium qStadium = QStadium.stadium;

                JPAQuery<StadiumDetailDTO> query = jpaQueryFactory
                                .select(new QStadiumDetailDTO(qStadium.startTime, qStadium.endTime, qStadium.name,
                                                qStadium.lat, qStadium.lon, qStadium.address))
                                .from(qStadium)
                                .where(qStadium.id.eq(id));

                return query.fetchOne();
        }

		@Override
        public SportCategoryDTO findCategoryByStadiumId(Long categoryId) {
                QSportCategory qSportCategory = QSportCategory.sportCategory;

                JPAQuery<SportCategoryDTO> query = jpaQueryFactory
                                .select(new QSportCategoryDTO(qSportCategory.id, qSportCategory.sport))
                                .from(qSportCategory)
                                .where(qSportCategory.id.eq(categoryId));

                return query.fetchOne();
        }
  }
public interface StadiumCourtCustomRepository {

    List<StadiumCourtDTO> findStadiumCourtByStadiumId(@Param("stadiumId") Long stadiumId);
}
@Repository
@RequiredArgsConstructor
@Transactional
public class StadiumCourtRepositoryImpl implements StadiumCourtCustomRepository {

    private final JPAQueryFactory jpaQueryFactory;

    @Override
    public List<StadiumCourtDTO> findStadiumCourtByStadiumId(Long stadiumId) {
        QStadiumCourt qStadiumCourt = QStadiumCourt.stadiumCourt;

        JPAQuery<StadiumCourtDTO> query = jpaQueryFactory
                .select(new QStadiumCourtDTO(qStadiumCourt.id, qStadiumCourt.title, qStadiumCourt.content,
                        qStadiumCourt.capacity, qStadiumCourt.courtPrice, qStadiumCourt.fileInfo))
                .from(qStadiumCourt)
                .where(qStadiumCourt.stadium.id.eq(stadiumId));

        return query.fetch();
    }

DTO

@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
public class StadiumDetailDTO {

    private LocalTime startTime;
    private LocalTime endTime;
    private String name;
    private Double lat;
    private Double lon;
    private StadiumAddress address;
    private SportCategoryDTO category;
    private List<StadiumCourtDTO> stadiumCourt;
    private FileInfoResponseDTO fileInfo;

    public StadiumDetailDTO(FileInfoResponseDTO fileInfo) {
        this.fileInfo = fileInfo;
    }

    public StadiumDetailDTO(List<StadiumCourtDTO> stadiumCourt) {
        this.stadiumCourt = stadiumCourt;
    }

    public StadiumDetailDTO(SportCategoryDTO category) {
        this.category = category;
    }

    @QueryProjection
    public StadiumDetailDTO(LocalTime startTime, LocalTime endTime, String name, Double lat, Double lon,
            StadiumAddress address) {
        this.startTime = startTime;
        this.endTime = endTime;
        this.name = name;
        this.lat = lat;
        this.lon = lon;
        this.address = address;
    }

}

카테고리, 사진파일, 코트list 는 별도의 dto로 만들어 줌

  • @QueryProjection : 어노테이션을 사용하면 쿼리 결과를 DTO 객체로 바로 매핑할 수 있다.

요 쿼리를 매핑.

 

동일 방식으로 진행!

@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
public class SportCategoryDTO {

    private Long id;
    private String sport;

    @QueryProjection
    public SportCategoryDTO(Long id, String sport) {
        this.id = id;
        this.sport = sport;
    }
}
@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
public class FileInfoResponseDTO {
    private Long id;
    private FileInfoSource type;

    @QueryProjection
    public FileInfoResponseDTO(Long id, FileInfoSource type) {
        this.id = id;
        this.type = type;
    }
}
@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode
public class StadiumCourtDTO {
    private Long id;
    private String title;
    private String content;
    private Integer capacity;
    private Integer courtPrice;

    private FileInfo fileInfo;

    @QueryProjection
    public StadiumCourtDTO(Long id, String title, String content, Integer capacity, Integer courtPrice,
            FileInfo fileInfo) {
        this.id = id;
        this.title = title;
        this.content = content;
        this.capacity = capacity;
        this.courtPrice = courtPrice;
        this.fileInfo = fileInfo;
    }
}

결과

요청주소 (get)
http://localhost:8080/api/user/stadium/{stadiumId}

요청 바디
- jwt token

응답 바디

{
    "status": 200,
    "msg": "성공",
    "data": {
        "id": 1,
        "startTime": "09:00:00",
        "endTime": "18:00:00",
        "name": "a 야구장",
        "lat": 35.1846,
        "lon": 128.9863,
        "address": "부산시",
        "category": {
            "id": 1,
            "sport": "야구"
        },
        "sourceFile": {
            "id": 5,
            "fileUrl": "https://3-sporting.s3.ap-northeast-2.amazonaws.com/Stadium/%EC%95%BC%EA%B5%AC_Stadium.png"
        },
        "courts": [
            {
                "id": 1,
                "title": "a 야구장(코트1)",
                "content": "최신 시설 야구장",
                "capacity": 22,
                "price": 40000,
                "sourceFile": {
                    "id": 9,
                    "fileUrl": "https://3-sporting.s3.ap-northeast-2.amazonaws.com/Court/%EC%95%BC%EA%B5%AC_Court.png"
                }
            }
        ]
    }
}
728x90

'Project > Final Project - Sporting (매칭)' 카테고리의 다른 글

[2단계] Admin court 등록 승인  (0) 2023.05.01
[2단계] Admin page Court view  (0) 2023.05.01
[1단계] Company Update Form  (0) 2023.05.01
[3단계] sentry.io 적용  (0) 2023.05.01
[1단계] 기업 회원가입  (0) 2023.04.26