JPA와 Querydsl 활용

김혁준·2024년 7월 7일

JPA

목록 보기
16/16

설계 전략 : 기본적인 메서드는 스프링 데이터 JPA로 작성, 동적 쿼리나 페이징은 Querydsl 활용

스프링 데이터 JPA 레포지토리 생성

public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom {
     List<Member> findByUsername(String username);
     
     // 페이징 연동. 스프링 데이터의 Page, Pageable 활용하기
     Page<MemberTeamDto> searchPageSimple(MemberSearchCondition condition,
 Pageable pageable);
 
     Page<MemberTeamDto> searchPageComplex(MemberSearchCondition condition,
 Pageable pageable);
 }

사용자 정의 인터페이스 생성

public interface MemberRepositoryCustom {
     List<MemberTeamDto> search(MemberSearchCondition condition);
 }
 
// Querydsl 활용 사용자 정의 인터페이스 구현
public class MemberRepositoryCustomImpl implements MemberRepositoryCustom {
    private final JPAQueryFactory queryFactory;
    public MemberRepositoryImpl(EntityManager em) {
        this.queryFactory = new JPAQueryFactory(em);
}
	@Override
	//회원명, 팀명, 나이(ageGoe, ageLoe)
	public List<MemberTeamDto> search(MemberSearchCondition condition) {
        return queryFactory
                .select(new QMemberTeamDto(
				        member.id,
				        member.username,
				        member.age,
				        team.id,
				        team.name))
				.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 isEmpty(username) ? null : member.username.eq(username);
}

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

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

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

데이터 조회

// fetchResults가 Deprecated 됨. fetch 사용
List<MemberTeamDto> results = queryFactory
                .select(new QMemberTeamDto(
                        member.id,
                        member.username,
                        member.age,
                        team.id,
                        team.name))
                .from(member)
                .leftJoin(member.team, team)
                .where(usernameEq(condition.getUsername()),
                        teamNameEq(condition.getTeamName()),
                        ageGoe(condition.getAgeGoe()),
                        ageLoe(condition.getAgeLoe()))
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

전체 카운트 조회

// fetchCount가 Deprecated 됨. 대신 select 절에서 count 메서드 사용
Long total = queryFactory
                .select(member.count())
                .from(member)
                .leftJoin(member.team, team)
                .where(usernameEq(condition.getUsername()),
                        teamNameEq(condition.getTeamName()),
                        ageGoe(condition.getAgeGoe()),
                        ageLoe(condition.getAgeLoe()))
                .fetchOne();
return new PageImpl<>(content, pageable, total);

정렬

정렬은 조건이 조금만 복잡해져도 Pageable의 Sort 기능을 사용하기 어렵다. 동적 정렬 기능이 필요하면 파라미터를 받아서 직접 처리하자.

출처 : 실전! Querydsl

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-JPA-%EC%8B%A4%EC%A0%84/dashboard

0개의 댓글