Gyuseok
Dreaming_developer
Gyuseok
  • 분류 전체보기 (39)
    • Note (0)
    • TIL (8)
    • 일상 (1)
    • git & git hub (1)
    • Algorithm (14)
    • JAVA (5)
    • Spring & SpringBoot (10)
    • 기업연계 프로젝트 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 관리자
  • 티스토리
  • 글작성

공지사항

인기 글

태그

  • 국비지원교육
  • Builder
  • MegabyteSchool
  • 메가바이트스쿨
  • lombok
  • 개발자취업부트캠프
  • java
  • 패스트캠퍼스
  • pattern
  • 내일배움카드

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Gyuseok

Dreaming_developer

Spring & SpringBoot

dsl 에 subquery 사용 경험

2023. 6. 17. 22:05

토이 프로젝트를 진행 하던중, dsl에서 subquery를 사용할 일이 생겼다.

내가 구축한 DB ERD는

erd

위 사진과 같은데 이중 vote와 posting의 관계에 있어서 문제가 있었다.

좋아요의 경우 vote.liked에 1

싫어요의 경우 vote.liked에 -1 이 들어가는 모델을 생각하고 DB를 구현 했었는데, 

좋아요 개수로 where 절에 제약을 만드는 경우는 subquery가 정상적으로 작동했다.

private BooleanExpression filterByLikes(Integer likes) {
    if (likes == null) {
        return null;
    }
    return JPAExpressions
            .select(vote.count())
            .from(vote)
            .where(vote.posting.eq(posting).and(vote.like.eq(1)))
            .goe(Long.valueOf(likes));
}

하지만 문제는 다른 곳 에서 발생했다.

select p.* from posting p left outer join vote v on p.pk =v.posting group by p.pk order by (select count(*) from vote v2 where v2.posting =p.pk and v2.liked =1 ) desc ;

위 query와 같이 포스팅 중 vote의 like가1 인 경우가 많은 순으로 정렬 하려 했다.

하지만 dsl에서 코드를 작성하던 중 , OrderSpecifier 에서는 subquery를 사용 할수 없다는 것을 알았다.

시간순으로 말해보겠다.

이틀동안 OrderSpecifier 어떻게든 subquery를 사용하려 애썻다.

처음에는 가볍게

return new OrderSpecifier<>(Order.DESC,vote.like.eq(1).count());

이렇게 하면 될줄 알았다.

하지만 쿼리는 

order by count(vote.like = ?2) desc

으로 나가고 있었고, subquery로 작성하기 위해 

QVote vote2 = new QVote("v2");
JPQLQuery<Long> subquery = JPAExpressions.select(vote2.count())
        .from(vote2)
        .where(vote2.posting.eq(posting), vote2.like.eq(1));
return new OrderSpecifier<>(Order.DESC, subquery);

JPQLQuery를 이용해 쿼리를 만든 후 OrderSpecifier 에 넣어보았지만,

order by (select count(v2)
from com.cutegyuseok.freetalk.posting.entity.Vote v2
    where v2.posting = posting and v2.like = ?2) desc

쿼리가 제대로 나가는 것 처럼 보였지만\

NoViableAltException: unexpected AST node: query

오류가 났다.

쿼리가 올바르게 작성되지 않았거나 데이터가 옳바르지 않을때 생기는 오류인 것으로 알고있다.

다른 여러가지 시도도 정말 많이 해봤다.

그러던중 곰곰히 생각해보니, 내게 필요한 것은 좋아요의 수만 필요하고, 싫어요의 경우 보여지는 경우에 반영이 되지 않아도 되었다.

싫어요가 -1이였기 때문에 sum을 사용하지 않고 서브쿼리로 count 하였던 것인데 0을 사용하면 sum을 사용해도 된다.

따라서 좋아요 기능의 방식을 좋아요는 1 싫어요는 0 으로 바꾸어 적용하고 sum을 이용해 

case "LIKES":
    return new OrderSpecifier<>(Order.DESC, vote.like.sum());

으로 구현하였더니 정상적으로 작동하였다.

https://github.com/cutegyuseok/FreeTalk-ToyProject/blob/master/src/main/java/com/cutegyuseok/freetalk/posting/repository/PostingRepositoryCustomImpl.java

'Spring & SpringBoot' 카테고리의 다른 글

JPA SQL 오류 경험  (0) 2023.02.05
HashTag 검색 SQL 구현해보기  (0) 2023.01.27
Spring security 시작하기  (0) 2023.01.20
MockMVC  (0) 2023.01.13
SpringBoot JPA 사용하기  (0) 2022.12.30
    'Spring & SpringBoot' 카테고리의 다른 글
    • JPA SQL 오류 경험
    • HashTag 검색 SQL 구현해보기
    • Spring security 시작하기
    • MockMVC
    Gyuseok
    Gyuseok

    티스토리툴바