Spring Data Jpa에서 maxResults(limit) 설정은 어떻게?

박진형·2022년 2월 5일
1

JPA

목록 보기
6/7

Spring Data JPA에서 maxResult(limit) 설정은 어떻게?

단순히 데이터가 존재하는지 안하는지 확인하는 경우 exists를 활용하는 것이 좋다.
그 이유는 전에 포스팅한 글에 잘 나와있다.

이번에 프로젝트를 진행하면서 Spring Data JPA를 적극 사용해보기로 하면서 기존에 JPQL의 setMaxResults를 이용해 exists 쿼리를 구현을 한 것을 Spring Data JPA 방식으로 변경해야 했다. 하지만 Spring Data JPA의 @Query 어노테이션은 setMaxResults를 지원하지 않는 듯 했다.
그렇다면 limit 설정 방법에는 쿼리 메소드를 이용하는 방식과 Paging을 이용하는 방식이 있다고한다.

쿼리 메소드 방식

쿼리 메소드는 메소드의 이름으로 쿼리를 자동으로 생성 시켜주는 것인데.

아래와 같이 사용하면 Count 쿼리를 쓰면서 limit 1로 자동 설정해주어 exists와 같은 동작을 하게 된다.

void existsById(String id);

하지만 여기서 내가 겪은 문제점은 테이블끼리 조인을 하고 WHERE절에 조인한 테이블의 attribute를 사용해야할 때였다.

이럴때엔 페이징을 이용하도록 한다.

Paging 이용 방식

아래와 같이 조인을 하고 조건을 넣어주기 때문에 쿼리 메소드를 사용할 수 없기에 @Query 어노테이션을 사용해야했지만 @Query 어노테이션에는 따로 MaxResults(limit)을 설정할 수 없다는게 문제 였다.

 @Query("SELECT tm FROM TeamMember tm JOIN Member m ON m.id=tm.member.id WHERE tm.team.id =:teamId AND m.id=:memberId")

여기서 페이징을 이용하면 해결할 수 있는데 paging을 이용해서 페이지의 사이즈를 1로하고 0번째 페이지를 쿼리하는 것이다.

아래와 같이 우선 페이징을 사용할 수 있도록 매개변수의 뒷부분에 Pageable을 추가한 뒤에

@Query("SELECT tm FROM TeamMember tm JOIN Member m ON m.id=tm.member.id WHERE tm.team.id =:teamId AND m.id=:memberId")
    List<TeamMember> findWithPagingByTeamIdAndMemberId(@Param("teamId") Long teamId, @Param("memberId") String memberId, Pageable pageable);

아래와 같이 exists 함수처럼 동작할 수 있도록 메소드를 만든다 일종의 wrapping을 하는것이다.

default boolean existsByTeamIdAndMemberId(Long teamId,  String memberId)
    {
        return findWithPagingByTeamIdAndMemberId(teamId, memberId, PageRequest.of(0, 1)).size() == 1 ? true : false;
    }

이렇게하면 아래와 같이 limit절이 들어가면서 1개의 데이터만 찾을 수 있다.

Hibernate: 
    select
        teammember0_.team_member_id as team_mem1_14_,
        teammember0_.created_date as created_2_14_,
        teammember0_.last_modified_date as last_mod3_14_,
        teammember0_.created_by as created_4_14_,
        teammember0_.last_modified_by as last_mod5_14_,
        teammember0_.member_number as member_n7_14_,
        teammember0_.team_id as team_id8_14_,
        teammember0_.type as type6_14_ 
    from
        team_member teammember0_ 
    inner join
        member member2_ 
            on teammember0_.member_number=member2_.member_number 
    inner join
        member member1_ 
            on (
                member1_.member_id=member2_.member_id
            ) 
    where
        teammember0_.team_id=? 
        and member1_.member_id=? limit ?

0개의 댓글