QueryDSL Spring Data JPA + 동적 쿼리

Repository 작성

 

Repository 구성

 

 

MemberRepository

public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom{

    // select m from Member m where m.username = ?
    List<Member> findByUsername(String username);
}

 

 

MemberRepositoryCustom

public interface MemberRepositoryCustom {
    List<MemberTeamDto> search(MemberSearchCondition condition);
}
  • Query DSL로 만들 동적 쿼리인 search 메서드

 

 

MemberTeamDto

  • 조회할 Member와Team 정보를 추출하기 위해 그에 맞게 최적화한 DTO를 생성해줍니다.
  • 여기선 @QueryProjection을 쓰도록 하겠습니다. DTO에 담는 여러가지 방법을 알고 싶은 경우 해당 문구를 클릭해주세요.
@Data
public class MemberTeamDto {
    private Long memberId;
    private String username;
    private int age;
    private Long teamId;
    private String teamName;

    @QueryProjection
    public MemberTeamDto(Long memberId, String username, int age, Long teamId, String teamName) {
        this.memberId = memberId;
        this.username = username;
        this.age = age;
        this.teamId = teamId;
        this.teamName = teamName;
    }
}

 

 

MemberSearchCondition

  • 동적 쿼리 조건을 검사하기 위해 따로 MemberSearchCondition 클래스를 만들어줍니다.
@Data
public class MemberSearchCondition {

    private String username;
    private String teamName;
    private Integer ageGoe;
    private Integer ageLoe;
}

 

 

MemberRepositoryImpl

@RequiredArgsConstructor
public class MemberRepositoryImpl implements MemberRepositoryCustom{
	
    private final JPAQueryFactory queryFactory;

    @Override
    public List<MemberTeamDto> search(MemberSearchCondition condition) {
        return queryFactory
                .select(new QMemberTeamDto(
                        member.id.as("memberId"),
                        member.username,
                        member.age,
                        team.id.as("teamId"),
                        team.name.as("teamName")
                ))
                .from(member)
                .leftJoin(member.team, team)
                .where(
                        usernameEq(condition.getUsername()),
                        teamNameEq(condition.getTeamName()),
                        ageGoe(condition.getAgeGoe()),
                        ageLoe(condition.getAgeLoe())
                )
                .fetch();
    }

    private BooleanExpression usernameEq(String username) {
        return hasText(username) ? member.username.eq(username) : null;
    }

    private BooleanExpression teamNameEq(String teamName) {
        return hasText(teamName) ? team.name.eq(teamName) : null;
    }

    private BooleanExpression ageGoe(Integer ageGoe) {
        return ageGoe != null ? member.age.goe(ageGoe) : null;
    }

    private BooleanExpression ageLoe(Integer ageLoe) {
        return ageLoe != null ? member.age.loe(ageLoe) : null;
    }

    private BooleanExpression ageBetween(Integer ageLoe, Integer ageGoe) {
        return ageLoe(ageLoe).and(ageGoe(ageGoe));
    }
}