인프런 커뮤니티 질문&답변

최하준님의 프로필 이미지
최하준

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

주문 검색 기능 개발

안녕하세요! 동적쿼리에 대한 질문이 있습니다.

작성

·

445

0

현재 2년차가 되가고 있는 주니어개발자입니다 ( _ _)

아직 경험이 많이 없어 현재 쿼리를 처리하는 퍼시스턴트 프레임워크를 mybaits 정도 밖에 써보지 못 했습니다

선생님께서 말씀하신 것처럼 쿼리를 JPQL로 작성해서 처리할 수 있다고 하셨는데...

아래는 제가 mybatis로 api 처리하고 있는 쿼리입니다. 이런 다소 지저분하고 복잡한 쿼리도 실무에서는 JPQL로 처리를 하나요??? 

SELECT /* windowClosingPosData */
b.paymentType
,MAX(b.gdName) as gdName
,b.payMethod
,SUM(b.personCnt) as personCnt /* 수량 */
,SUM(b.price) as price /* 금액 */
,SUM(b.discountCount) as discountCnt /* 할인매수 */
,SUM(b.discountAmount) as discount /* 할인금액 */
FROM (
SELECT
a.paymentType
,a.gdName
,a.payMethod
,(
CASE
WHEN a.paymentType = 'PAY'
THEN a.ticketCount
WHEN a.paymentType = 'CANCEL'
THEN a.refundCount
ELSE 0
END
) as personCnt /* 수량 */
,(
CASE
WHEN a.paymentType = 'PAY'
THEN a.ticketAmount
WHEN a.paymentType = 'CANCEL'
THEN a.refundAmount
ELSE 0
END
) as price /* 금액 */

,a.discountCount /* 할인 수량 */
,a.discountAmount /* 할인 금액 */

FROM (
SELECT
'PAY' as paymentType
,gd.gd_name as gdName
,pm.pm_pay_method as payMethod
,rd.init_rs_ticket_cnt as ticketCount /* 발권매수 */
,(rd.init_rs_ticket_cnt * rd_price) as ticketAmount /* 발권금액 */
,0 as refundCount /* 환불매수 */
,0 as refundAmount /* 환불금액 */
,(
CASE
WHEN ifnull(rd.dc_unit_price,0) > 0
THEN rd.init_rs_ticket_cnt
ELSE 0
END
) as discountCount /* 할인매수 */
,(rd.init_rs_ticket_cnt * rd.dc_unit_price) as discountAmount
FROM t_reserve_detail rd
INNER JOIN t_reserve rs
ON rd.rs_seq = rs.rs_seq
INNER JOIN t_goods gd
ON rs.gd_seq = gd.gd_seq
INNER JOIN t_payment pm
ON rs.rs_seq = pm.rs_seq
AND pm.pm_payment_type = 'PAY'
WHERE
EXISTS (
SELECT
trdp.rs_seq
FROM t_reserve_detail_person trdp
WHERE trdp.tkt_date = DATE_FORMAT(#{searchDate}, '%Y%m%d')
AND trdp.idkey = #{idkey}
AND trdp.tkt_win_cd = #{winCd}
AND trdp.rs_seq = rs.rs_seq
)
AND (rs.gd_package_yn = 'Y' OR (rs.rs_package_yn = 'N' AND rs.gd_package_yn = 'N'))
AND rs.insert_idkey = #{memberSeq}
UNION ALL
SELECT
'CANCEL' as paymentType
,gd.gd_name as gdName
,pm.pm_pay_method as payMethod
,0 as ticketCount /* 발권매수 */
,0 as ticketAmount /* 발권금액 */
,rd.cancel_ticket_cnt as refundCount /* 환불매수 */
,(rd.cancel_ticket_cnt * rd_price) as refundAmount /* 환불금액 */
,0 as discountCount /* 할인매수 */
,0 as discountAmount
FROM t_reserve_detail rd
INNER JOIN t_reserve rs
ON rd.rs_seq = rs.rs_seq
INNER JOIN t_goods gd
ON rs.gd_seq = gd.gd_seq
INNER JOIN t_payment pm
ON rs.rs_seq = pm.rs_seq
AND pm.pm_payment_type = 'PAY'
WHERE
EXISTS (
SELECT
trdp.rs_seq
FROM t_reserve_detail_person trdp
WHERE trdp.tkt_date = DATE_FORMAT(#{searchDate}, '%Y%m%d')
AND trdp.idkey = #{idkey}
AND trdp.cancel_win_cd = #{winCd}
AND trdp.cancel_member_seq = #{memberSeq}
AND trdp.rs_seq = rs.rs_seq
)
AND (rs.gd_package_yn = 'Y' OR (rs.rs_package_yn = 'N' AND rs.gd_package_yn = 'N'))
AND rs.rs_status = 'D'
) a
) b
GROUP BY b.paymentType
,b.payMethod
ORDER BY b.payMethod, b.paymentType DESC

JPQL 강의도 들을 계획이지만 이렇게 복잡한 부분을 java단에서 처리한다는게 상상이 되지 않아서 질문드려봅니다 ㅠㅠ

답변 1

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 하준님

JPA를 사용하더라도 복잡한 통계성 쿼리는 네이티브 SQL을 직접 사용하는 편입니다.

추가로 JPA는 from 절의 서브쿼리가 지원되지 않기 때문에, 이런 경우에도 네이티브 SQL을 사용해야 합니다.

관련해서 JPQL을 학습해보시면, 장점과 한계점을 함께 학습하실 수 있을거에요.

화이팅!

최하준님의 프로필 이미지
최하준
질문자

친절한 답변 너무 감사합니다! 최근에 너무 바빠서 강의만 듣고 실습은 못하고 있는데ㅠㅠ

꼭 실습까지 다시한번 완료해서 제껄로 만들겠습니다!! 감사합니다!!!

김영한님의 프로필 이미지
김영한
지식공유자

백문이 불여일타입니다! 실습 필수! ㅋㅋ 화이팅!

최하준님의 프로필 이미지
최하준

작성한 질문수

질문하기