DevBoi

[JPA] QueryDsl 여러 기능 정리 본문

Develop/[JPA]

[JPA] QueryDsl 여러 기능 정리

HiSmith 2023. 8. 19. 16:38
반응형

1) BooleanBuilder, BolleanExpression 사용

 

비슷한 용도이지만 내 생각에 두개의 용도는  다르다.

BooleanExpression은 null인 경우 null을 반환해주면서, 조건에서 제외가 된다.

즉 특정 조건에 따라서 다이나믹하게 조건절이 추가되어야 하는경우, 심하면 없어도되는경우 BooleanExpression을 사용한다.

BooleanBuilder는 항상 객체가 생성이 되지만

복잡한 조건절의 쿼리를 생성해야할 때 이걸 사용하게 되면, 그나마 보기 쉽고 조합을 자유롭게 해줄수있다

다만 무조건 사용해야하고 복잡한 조건절의 조합 도구라고 보면된다.

 

물론 두개다 때에 따라서 용도와 장점과 어긋나게 사용은 가능하지만

장단이 있으니 그에 따라 맞게 사용하면 좋을 것 같다.

 

BooleanBuilder를 사용한 예시이다. where 절에 그냥 builder를 넣어주면 된다.

 BooleanBuilder builder = new BooleanBuilder();
    builder.and(friend.sourceId.eq(userId).and(friend.status.eq(FriendStatus.FRIEND.getStatus()))).not();
    builder.and(friend.sourceId.ne(userId).and(friend.targetId.ne(userId)));

 

2) Projection.fields 사용

 

두개 이상의 테이블을 조인할때, 한개의 객체를 생성해서

해당 프로젝션으로 해당 객체에 필드를 꽂아줬다.

이방식이 좀더 나은듯해서 통일했다.

List<FriendResDto>  result =  queryFactory.select(
      Projections.fields(
          FriendResDto.class,
          user.userId,
          user.nickname,
          user.introduce,
          user.thumbnailImageUrl,
          friend.status
        )
      )

 

3) Not in 조건절 사용

사실 쓰기 싫었는데, 안쓸수가없었다.

여러개의 행으로 설계를 하고, 특정 조건을 전체 대상에서 제외하는 로직이 앞으로도 많을것같다.

무튼 하위 같이 짜면 된다.

List<FriendResDto>  result =  queryFactory.select(
      Projections.fields(
          FriendResDto.class,
          user.userId,
          user.nickname,
          user.introduce,
          user.thumbnailImageUrl,
          friend.status
        )
      ).distinct()
      .from(user,friend)
      .where(
        user.userId.eq(friend.sourceId),
        friend.sourceId.ne(userId).and(friend.targetId.ne(userId)),
        user.userId.notIn(
          JPAExpressions.select(friend.targetId)
            .from(friend)
            .where(friend.sourceId.eq(userId).and(friend.status.eq(FriendStatus.FRIEND.getStatus())))
        )
      )
      .stream()
      .toList();

 

4. distinct 지원 사용

여러가지 방법이 있겠지만 복수개의 프로젝션으로 데이터를 받는 경우,

해당 데이터를 distinct하기 어렵다.

무튼 querydsl에서는 select 옆에 distinct 메서드 체이닝으로 중복 검사를 할 수 있다. 참고

Projections.fields(
          FriendResDto.class,
          user.userId,
          user.nickname,
          user.introduce,
          user.thumbnailImageUrl,
          friend.status
        )
      ).distinct()
반응형

'Develop > [JPA]' 카테고리의 다른 글

[JPA] ElementCollection  (0) 2023.08.28
[JPA] QueryDsl LeftJoin,SelfJoin  (0) 2023.08.19
[JPA] 친구 관련 API개발  (0) 2023.08.19
[JPA] QueryDsl 친구 관련 설계  (0) 2023.08.16
[JPA] QueryDsl query logging 설정  (0) 2023.08.14