Spring/프로젝트 코드 리뷰
Spring WatchaPedia 클론코딩 프로젝트 취향 분석(선호 배우, 국가, 장르, 감상 시간)
code2772
2023. 3. 8. 01:30
728x90
반응형
🎬 선호배우 분석 Service
public List<Map.Entry<String, String>> peopleCnt(Long userIdx){
Map<Long, Integer> peopleMap = new HashMap<>();
List<Long> movIdxs = starRepository.findStarMovie(userIdx);
List<String> peopleList = List.of(movieRepository.findPeopleList(movIdxs).toString()
.split("\\[")[1].split("]")[0].split(", "));
for(String str: peopleList){
String[] personList = str.split(",");
for(String per : personList){
if(per.contains("주연")){
Long personIdx = 0L;
try {
if (per.contains("(")) {
personIdx = Long.valueOf(per.split("\\(")[0]);
} else personIdx = Long.valueOf(per);
if (peopleMap.get(personIdx) != null) {
peopleMap.put(personIdx, 1 + peopleMap.get(personIdx));
} else {
peopleMap.put(personIdx, 1);
}
}catch(NumberFormatException e){}
}
}
}
List<Map.Entry<Long, Integer>> entryList = new LinkedList<>(peopleMap.entrySet());
entryList.sort(((o1, o2) -> o2.getValue() - o1.getValue()));
Pageable pageable = PageRequest.of(0, 1);
Map<String, String> resultMap = new HashMap<String, String>();
for(int i=0; i<=5; i++){
try{
Person person = personRepository.findById(entryList.get(i).getKey()).get();
resultMap.put((person.getPerPhoto()!=null?person.getPerPhoto()+"|":"")+person.getPerName()+","+person.getPerIdx()
,entryList.get(i).getValue()+","+movieRepository.actorMovie("%,"+person.getPerIdx()+"(주연%",pageable).get(0));
}catch (IndexOutOfBoundsException e){
System.out.println("인물 부족");
}
}
List<Map.Entry<String, String>> result = new LinkedList<>(resultMap.entrySet());
result.sort(((o1, o2) -> Integer.parseInt(o2.getValue().split(",")[0]) - Integer.parseInt(o1.getValue().split(",")[0])));
return result;
}
사용자가 감상한 또는 평가한 tb_star 테이블의 idx를 찾는다. 이 후 이 tb_star의 idx와 콘텐츠 idx의 연관성을 찾아들어가 해당 콘텐츠의 출연/제작, 국가, 장르, 런닝타임 등을 뽑아와 카운트를 하여 나의 취향을 분석하는 부분이다.
🎬 콘텐츠(영화) Repository
@Query(value = "SELECT movCountry, COUNT(movCountry) FROM tbMovie WHERE movIdx in :idxs GROUP BY movCountry HAVING COUNT(movCountry) > 0")
List<String> findCountryCnt(@Param("idxs") List<Long> idxs);
@Query(value = "SELECT movGenre, COUNT(movGenre) FROM tbMovie WHERE movIdx in :idxs GROUP BY movGenre HAVING COUNT(movGenre) > 0")
List<String> findGenreCnt(@Param("idxs") List<Long> idxs);
@Query(value = "SELECT movPeople FROM tbMovie WHERE movIdx in :idxs")
List<String> findPeopleList(@Param("idxs") List<Long> idxs);
@Query(value = "SELECT movTime FROM tbMovie WHERE movIdx in :idxs")
List<String> timeList(@Param("idxs") List<Long> idxs);
@Query(value = "SELECT movTitle FROM tbMovie WHERE movPeople LIKE :idx ORDER BY movIdx DESC")
List<String> actorMovie(@Param("idx") String idx, Pageable pageable);
@Query는 domain model이 아닌 Repository안에있는 메서드에 위치, 테이블이 아닌 엔티티 객체를 대상으로 검색하는 객체지향 쿼리, SQL 추상화로 인해 특정 db sql 에 의존하지 않음. @Param 을 통해 매개변수로 넘어온 값을 JPQL에 들어갈 변수로 지정한다. 더 복잡한 SQL 문을 스프링에서 사용하기 위해 Query 엔티티를 사용하였다.
🎬 선호배우 타임리프
<ul class="css-1m9zbc5-VisualUl" th:remove="all-but-first">
<li class="css-wj6fn0" th:each="person : ${actorMap}">
<a th:title="${#strings.contains(person.getKey(), '|')}?
(${#strings.arraySplit((#strings.arraySplit(person.getKey(),',')[0]),'|')[1]})
:${#strings.arraySplit(person.getKey(),',')[0]}" class="css-1aaqvgs-InnerPartOfListWithImage"
th:href="'/personDetail/'+${#strings.arraySplit(person.getKey(),',')[1]}">
<div class="css-cssveg">
<div class="css-13zlig9">
<div class="css-1q751em-ProfilePhotoImage"
th:styleappend="'background:url('+${#strings.arraySplit(person.getKey(),'|')[0]}+') no-repeat center;repeat center; background-size: cover;'"></div>
</div>
</div>
<div class="css-zoy7di">
<div class="css-qkf9j">
<div class="css-17vuhtq">
<div class="css-1pfpne2-PersonTitle e72a1w70"><span
class="css-1neatfa-PersonName e72a1w71" th:text="${#strings.contains(person.getKey(), '|')}?
(${#strings.arraySplit((#strings.arraySplit(person.getKey(),',')[0]),'|')[1]})
:${#strings.arraySplit(person.getKey(),',')[0]}">김태리</span><span
class="css-104v25a-PersonDetail e72a1w72" th:text="${#strings.arraySplit(person.getValue(),',')[0]}+'편'">100점 • 3편</span></div>
</div>
<div class="css-1evnpxk-StyledSubtitle" th:text="${#strings.arraySplit(person.getValue(),',')[1]}">리틀 포레스트</div>
</div>
<div></div>
</div>
</a></li>
1. 선호 배우는 먼저 HTML 내에 타임리프를 적용하였다. all-but-first와 th:each를 사용하여 리스트의 첫 번째 부분을 반복하였다.
2. 이전 디테일 페이지와 유사하게 먼저 DB에 있는 인물의 정보를 나누기 위해 split을 이용하여 나눠 인물들을 출력시켰다.
3. 선호배우와 유사하게 선호국가, 장르, 감상시간 모두 유사하게 추출하였다.
🎬 선호배우 웹페이지 출력화면
🎬 선호국가, 선호장르 웹페이지 출력화면
🎬 감상 시간 웹페이지 출력화면
반응형