Notice
Recent Posts
Recent Comments
Link
DevKim
[ Webtooniverse ] 웹툰 상세 페이지 개발 - 웹툰 장르, Review 리스트 본문
Spring Project/Webtooniverse
[ Webtooniverse ] 웹툰 상세 페이지 개발 - 웹툰 장르, Review 리스트
on_doing 2021. 7. 30. 23:33728x90
[ 설계 ]
기본적으로 장르와 웹툰은 다:다 관계이기 때문에,
WEBTOON_GENRE라는 중간 테이블을 생성하여 1:다 다:1 관계로 풀어서 설계하였다.
불필요한 쿼리문을 없애기위해, 아래와같이 최대한 연관관계는 모두 단방향 매핑으로 걸어주었다.
[ 요구 사항 분석 ]
- /api/v1/webtoon/{id} 로 GET 요청이 들어오면 다음과 같은 정보들을 DTO에 담아서 보내준다.
01. 웹툰 기본 정보
- 웹툰의 default 기본값으로, 변하지 않는 정보들이다.
- 단순히 DB에서 id값을 이용하여 가져온다.
[
{
"toonImg" : "웹툰 썸네일 이미지",
"toonTitle": "여신강림",
"toonAuthor": "야옹이",
"toonAge": "12세 이용가",
"realUrl":"https://comic.naver.com/webtoon/detail?titleId=703846&no=171&weekday=tue",
"toonContent": "네웹 대표 글로벌 인기작! 주경, 수호, 서준. 세 청춘의 두근두근 눈호강 로맨스~♡"
"toonWeekday" : "월",
"toonFlatform" : "네이버",
"finished": 0 /1
}
]
02. 웹툰의 장르 리스트 만들기
- 중간 테이블 역할을 하는 WebToonGenre 테이블은 조인 테이블의 역할만 수행한다.
즉, 각각의 FK 값 외에 다른 값이 들어가진 않는다.
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity
@Table(name = "WEBTOON_GENRE")
public class WebtoonGenre {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "toonGenreId")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="genreId")
private Genre genre;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "toonId")
private Webtoon webtoon;
public WebtoonGenre createWebToonGenre(Genre genre,Webtoon webtoon)
{
WebtoonGenre webtoonGenre = new WebtoonGenre();
webtoonGenre.genre=genre;
webtoonGenre.webtoon=webtoon;
return webtoonGenre;
}
}
- 쿼리를 날려보자
찾고 싶은 웹툰을 조건으로 inner조인을 한 뒤, 그것의 장르 리스트를 가져왔다.
@Query("SELECT wg.genre from WebtoonGenre wg inner join wg.webtoon on wg.webtoon=:webtoon")
List<Genre> findWebToonGenre(@Param("webtoon") Webtoon webtoon);
[ 테스트 코드 ]
- 일단 빠르게 기능들을 확인하기 위해 통합 테스트를 진행하였다.
- H2 DB로 데이터가 잘 매핑되는걸 확인하기 위해 Rollback은 false로 걸어주었다.
@Transactional
@Rollback(value = false)
@SpringBootTest
class WebtoonGenreTest {
@Autowired
private GenreRepository genreRepository;
@Autowired
private WebtoonRepository webtoonRepository;
@Autowired
private ReviewRepository reviewRepository;
@PersistenceContext
EntityManager em;
@Test
@DisplayName("웹툰의 장르가 잘 찾아와지는지 테스트")
public void test() throws Exception {
//given
//장르 저장
Genre g1 = createGenre("일상");
Genre g2 = createGenre("개그");
Genre g3 = createGenre("판타지");
genreRepository.save(g1);
genreRepository.save(g2);
genreRepository.save(g3);
//웹툰 저장
Webtoon w1 = createWebtoon("제목1", "작가1", "내용1");
Webtoon w2 = createWebtoon("제목2", "작가2", "내용2");
webtoonRepository.save(w1);
webtoonRepository.save(w2);
//when
//연관관계 설정
WebtoonGenre webtoonGenre1 = new WebtoonGenre();
WebtoonGenre wg1 = webtoonGenre1.createWebToonGenre(g1, w1);
WebtoonGenre wg2 = webtoonGenre1.createWebToonGenre(g2, w1);
WebtoonGenre webtoonGenre2 = new WebtoonGenre();
WebtoonGenre wg3 = webtoonGenre2.createWebToonGenre(g2, w2);
WebtoonGenre wg4 = webtoonGenre2.createWebToonGenre(g3, w2);
em.persist(wg1);
em.persist(wg2);
em.persist(wg3);
em.persist(wg4);
//then
List<Genre> webToonGenre = webtoonRepository.findWebToonGenre(w1);
assertThat(webToonGenre.get(0).getGenreType()).isEqualTo("일상");
assertThat(webToonGenre.get(1).getGenreType()).isEqualTo("개그");
List<Genre> webToonGenre2 = webtoonRepository.findWebToonGenre(w2);
assertThat(webToonGenre2.get(0).getGenreType()).isEqualTo("개그");
assertThat(webToonGenre2.get(1).getGenreType()).isEqualTo("판타지");
}
private Webtoon createWebtoon(String title, String author, String content) {
return Webtoon.builder()
.toonTitle(title)
.toonAuthor(author)
.toonContent(content)
.build();
}
private Genre createGenre(String type) {
return Genre.builder()
.genreType(type)
.build();
}
}
03. 리뷰 리스트 가져오기 (08.02 수정)
리뷰와 웹툰은 다:1 단방향 연관관계로, 비교적으로 단순한 구조이다.
- 쿼리를 날려보자
- content 내용이 null이 아닌 리뷰만 가져오도록 수정
@Query("select r from Review r inner join r.webtoon on r.webtoon.id=:toonId and r.reviewContent IS Not null")
List<Review> findReviewByWebToonId(@Param("toonId") Long toonId);
[ 테스트 코드 ]
위와 동일하게 통합 테스트로 진행하였다.
상세페이지를 모두 개발한 뒤, 단위테스트로 바꿔서 다시 테스트 코드를 작성할 예정이다.
@Test
@DisplayName("웹툰의 Review 가져오기")
public void 웹툰_리뷰_리스트_가져오기() throws Exception {
//given
//리뷰
Review review1 = Review.builder()
.reviewContent("리뷰 내용1")
.userPointNumber(4.5F)
.likeCount(13)
.build();
Review review2 = Review.builder()
.reviewContent(null)
.userPointNumber(4.5F)
.likeCount(13)
.build();
//웹툰
Webtoon w1 = createWebtoon("제목1", "작가1", "내용1");
Webtoon w2 = createWebtoon("제목2", "작가2", "내용2");
em.persist(w1);
em.persist(w2);
//유저
User user = User.builder()
.userName("홍길동")
.userEmail("abc@naver.com")
.userImg(1)
.userGrade(UserGrade.FIRST)
.build();
em.persist(user);
review1.insertWebToonAndUser(w1, user);
review2.insertWebToonAndUser(w1, user);
//when
em.persist(review1);
em.persist(review2);
//then
List<Review> reviewList = webtoonRepository.findReviewByWebToonId(w1.getId());
//내용이 null인 리뷰는 나오면 안됨
assertThat(reviewList.size()).isEqualTo(1);
assertThat(reviewList.get(0).getReviewContent()).isEqualTo(review1.getReviewContent());
}
728x90
'Spring Project > Webtooniverse' 카테고리의 다른 글
[ Webtooniverse ] 웹툰 상세 페이지 개발 - 웹툰 별점 등록하기 (0) | 2021.08.02 |
---|---|
[ Webtooniverse ] 웹툰 상세 페이지 개발 - 리뷰 좋아요 기능 & 리뷰 수정 및 삭제 (0) | 2021.08.01 |
[ Webtooniverse ] pymysql을 이용하여 Maria DB와 연동 & MySQL 쿼리문 (0) | 2021.07.28 |
[ Webtooniverse ] Maria DB 구축하기 - 네이버 웹툰 크롤링 (0) | 2021.07.28 |
[ Webtooniverse ] DB 설계 / Entity 설계 (2차 수정) (0) | 2021.07.28 |
Comments