사례1) SELECT 쿼리 출력할 때 null 값 변환을 위해 NVL()를 사용하였는데 SQL 실행 결과 시엔 정상적으로 출력되었으나 List에 모든 행이 제대로 담기지 않았다.
-> 데이터 타입의 문제라 생각해 TO_NUMBER(), CAST() 등의 Oracle 메서드를 사용해보았으나 해결안됨.
=> 어차피 null값이 java 변수에 담기면 각각의 기본값으로 변환되므로 서브쿼리에서 null값을 계산해야하는 경우가 아닌 메인 SELECT절에선 NVL()(그리고 다른 문자함수) 사용 지양하는 걸로.
cause) 박스오피스에 해당하는 영화가 API 호출했지만 얻지 못해 출력되지않은 것임을 알게되었다.. tbl_movie 테이블에 없었음.. 예상했던 상기 부분들이 원인 아닐수도..
-> 일단 LEFT OUTER JOIN tbl_movie m 으로 쿼리 수정하고 호출 API 개선하기로함
@Data
public class BoxOfficeWithStarDTO {
private BoxOfficeVO boxOfficeVO;
private String posterUrl;
private int prdtYear;
private String repNationNm;
private double avgStarRating;
private double userStarRating;
}
```java
public List<BoxOfficeWithStarDTO> getBoxOfficeWithStarList(@Param("showDate") String showDate, @Param("userid") String userid);
<resultMap type="com.moviepedia.domain.BoxOfficeWithStarDTO" id="boxOfficeWithStarDTO">
<result property="avgStarRating" column="avgstarrating"/>
<result property="userStarRating" column="userstarrating"/>
<result property="posterUrl" column="posterurl"/>
<result property="prdtYear" column="prdtyear"/>
<result property="repNationNm" column="repnationnm"/>
<association property="boxOfficeVO" javaType="com.moviepedia.domain.BoxOfficeVO">
<id property="showDate" column="showdate"/>
<id property="movieCd" column="moviecd"/>
<result property="rank" column="rank"/>
<result property="movieNm" column="movienm"/>
<result property="openDt" column="opendt"/>
<result property="audiCnt" column="audicnt"/>
<result property="audiAcc" column="audiacc"/>
<result property="updateDate" column="updatedate"/>
</association>
</resultMap>
<select id="getBoxOfficeWithStarList" resultMap="boxOfficeWithStarDTO">
SELECT DISTINCT b.rank, b.movieCd, b.movieNm, b.openDt, b.audiAcc, b.showDate
, m.posterUrl, m.prdtYear, m.repNationNm
<!-- , NVL(ROUND(AVG(s.starRating) OVER(PARTITION BY s.movieCd),1), 0) AS avgStarRating -->
, ROUND(AVG(s.starRating) OVER(PARTITION BY s.movieCd),1) AS avgStarRating
<!-- ?) NVL(, 0(or 0.0)) 이용 시 List에 제대로 안담김. 몇몇 행만 담김... to_number, cast도 안됨
=> 반환되는 데이터 타입의 문제 아닐까?
: 어차피 DTO엔 0.0으로 담기므로 할 필요없음.. -->
<if test="userid neq null">
, (SELECT ss.starRating FROM tbl_starRating ss WHERE ss.userid = #{userid} AND ss.movieCd = b.movieCd) AS userStarRating
</if>
FROM tbl_boxOffice b
JOIN tbl_movie m
ON (b.movieCd = m.movieCd)
LEFT OUTER JOIN tbl_starRating s
ON (b.movieCd = s.movieCd)
WHERE b.showDate = #{showDate}
ORDER BY rank ASC
</select>
@Data
public class DisplayMovieDTO {
private MovieVO movieVO;
private double avgStarRating;
private double userStarRating;
}
@Data
public class DisplayMovieDTO2 {
private String movieCd;
private String movieNm;
private int prdtYear;
private String repNationNm;
private String posterUrl;
private double avgStarRating;
private double userStarRating;
}
<resultMap type="com.moviepedia.domain.DisplayMovieDTO" id="displayMovieDTO">
<result property="avgStarRating" column="avgstarrating" />
<result property="userStarRating" column="userstarrating" />
<association property="movieVO" javaType="com.moviepedia.domain.MovieVO">
<id property="movieCd" column="moviecd"/>
<result property="movieNm" column="movienm"/>
<result property="movieNmEn" column="movieNmEn"/>
<result property="prdtYear" column="prdtyear"/>
<result property="openDt" column="openDt"/>
<result property="typeNm" column="typeNm"/>
<result property="prdtStatNm" column="prdtStatNm"/>
<result property="nationAlt" column="nationAlt"/>
<result property="genreAlt" column="genreAlt"/>
<result property="repNationNm" column="repNationNm"/>
<result property="repGenreNm" column="repGenreNm"/>
<result property="companyCd" column="companyCd"/>
<result property="companyNm" column="companyNm"/>
<result property="directorDetail" column="directorDetail"/>
<result property="showTm" column="showTm"/>
<result property="actorDetail" column="actorDetail"/>
<result property="watchGradeNm" column="watchGradeNm"/>
<result property="posterUrl" column="posterUrl"/>
<result property="storyText" column="storyText"/>
<result property="updateDate" column="updateDate"/>
<result property="commentCnt" column="commentCnt"/>
</association>
</resultMap>
<select id="getHighStarRatingMovieList" resultType="com.moviepedia.domain.DisplayMovieDTO2" >
SELECT ft.movieNm, ft.prdtYear, ft.repNationNm, ft.posterUrl, ft.movieCd
, ft.avgStarRating
FROM (
SELECT iv.movieCd, iv.movieNm, iv.prdtYear, iv.repNationNm, iv.posterUrl
, ROUND(AVG(s.starRating), 1) AS avgStarRating
, COUNT(s.starRating) AS cntStarRating
FROM (
SELECT m.movieCd, m.movieNm, m.prdtYear, m.repNationNm, m.posterUrl
FROM tbl_movie m
WHERE m.movieCd NOT IN (
SELECT movieCd
FROM tbl_starRating s
WHERE userid = #{userid})
) iv
INNER JOIN tbl_starRating s
/* INNER JOIN : 다른 유저들이 평가한 영화 중에서 출력 */
ON (iv.movieCd = s.movieCd)
GROUP BY iv.movieCd, iv.movieNm, iv.prdtYear, iv.repNationNm, iv.posterUrl
ORDER BY avgStarRating DESC, cntStarRating DESC
) ft
WHERE ROWNUM BETWEEN 1 AND 20
</select>