본문 바로가기
Spring/프로젝트 코드 리뷰

Spring 클론코딩 프로젝트 콘텐츠 DetailPage( 비슷한 장르의 작품 추천)

by code2772 2023. 3. 6.

[ 목차 ]

    728x90
    반응형

    🎬 MovieRespose - Containing 이용하여 유사 장르 뽑기

    List<Movie> findByMovGenreContaining(String genre);

    🎬 MovieService

    @Transactional(readOnly = true)
    public List<MovieResponse> similarGenre(String genre, Long movieIdx){
        List<MovieResponse> result = new ArrayList<>();
    
        List<Long> movieIdxList = new ArrayList<>(16);
        if(genre.contains("/")){
            List<String> genreList = Arrays.stream(genre.split("/")).toList();
            HashMap<Long, Integer> containMovie = new HashMap<>();
            for(String idx: genreList){
                for(Movie mov: movieRepository.findByMovGenreContaining(idx)){
                    containMovie.put(mov.getMovIdx(),
                            containMovie.get(mov.getMovIdx()) != null ?
                                    containMovie.get(mov.getMovIdx()) + 1 : 1
                    );
                }
            }
            List<Map.Entry<Long, Integer>> entryList = new LinkedList<>(containMovie.entrySet());
            entryList.sort(((o1, o2) -> o2.getValue() - o1.getValue()));
            for(Map.Entry<Long, Integer> entry : entryList){
                movieIdxList.add(entry.getKey());
            }
        }else{
            for(Movie idx: movieRepository.findByMovGenreContaining(genre)){
                movieIdxList.add(idx.getMovIdx());
            }
        }
    
        for(Long idx: movieIdxList){
            if(idx == movieIdx) continue;
            MovieDto dto = MovieDto.from(movieRepository.getReferenceById(idx));
            double sum = 0;
    
            if(dto.starList().size() > 0){
                for(Star star: dto.starList()){
                    sum += star.getStarPoint();
                }
                result.add(MovieResponse.of(dto.movIdx(), dto.movThumbnail(),dto.movTitle(),dto.movWatch(),Math.round((sum / dto.starList().size()) * 10.0) / 10.0));
            }else{
                result.add(MovieResponse.of(dto.movIdx(), dto.movThumbnail(),dto.movTitle(),dto.movWatch(),0.0));
            }
        }
        return result;
    }

    장르가 예를들어 액션/가족/코미디 와 같이 데이터베이스에 크롤링간 들어가있다. 그렇기 때문에 해당 장르와 유사한 장르를 구별하기 위해 

    List<String> genreList = Arrays.stream(genre.split("/")).toList();

    split을 해주어 genreList를 만들어 두었다. 그렇게 for문을 이용하여 반복을 돌려 기존에 만들어 준 Containing을 이용하여 장르가 겹치는 콘텐츠를 유사한 콘텐츠로 만들기
     
    🎬 MovieController 에서 이제 서비스에서 만들었던 similarGenre를 기입해준다.

    //        비슷한 장르 영화
            List<MovieResponse> similarGenre = movieService.similarGenre(movie.genre(), movie.idx());

     
    🎬 타임리프 출력 코드

     <!--    비슷한 작품 -->
        <attr sel="section[data-rowindex='13']" th:if="${similarGenre.size()} > 0">
            <attr sel="ul.css-27z1qm-VisualUl-ContentGrid" th:remove="all-but-first">
                <attr sel="li.css-1hp6p72" th:each="mov : ${similarGenre}">
                    <attr sel="a" th:title="mov.title" th:href="'/movie/' + ${mov.idx}"/>
                    <attr sel="img.css-qhzw1o-StyledImg" th:src="${mov.thumbnail}"/>
    
                    <attr sel="div.css-1qmeemv">
                        <!--                넷플릭스 아이콘-->
                        <attr sel="div.css-5o7sb2" th:if="${mov.watch} != null and ${#strings.contains(mov.watch,'aHR0cHM6Ly93d3cubmV0ZmxpeC5jb20vdGl0b')}"/>
                        <!--                왓챠 아이콘 -->
                        <attr sel="div.css-oobk33" th:if="${mov.watch} != null and ${#strings.contains(mov.watch,'aHR0cHM6Ly93YXRjaGEuY29tL3dhd')}"/>
                    </attr>
                    <attr sel="div.css-ixy093">
                        <attr sel="div.css-niy0za" th:text="${mov.title}"/>
                        <attr sel="div.css-m9i0qw" th:if="${mov.avgStar} != 0.0" th:text="'평균 ★ ' + (${mov.avgStar} != 0 ? ${mov.avgStar} : _)"/>
                    </attr>
                </attr>
            </attr>
        </attr>
    </thlogic>

    🎬 해당 콘텐츠와 비슷한 작품 추천 화면

    반응형