QueryDSL - 사용자 정의 리포지토리

박민수·2023년 11월 14일
0

JPA

목록 보기
8/24
post-thumbnail

QueryDSL 사용자 정의 리포지토리

QueryDSL을 사용하려면 구현 코드를 만들어야 하는데 스프링 데이터는 인터페스로 동작하기 때문에 내가 원하는 구현 코드를 넣으려면 사용자 정의 리포지토리라는 조금 복잡한 방법을 사용해야 한다.

인터페이스 작성

public interface MemberRepositoryCustom {
	List<MemberTeamDto> search(MemberSearchCondition condition);
}

인터페이스 구현

public class MemberRepositoryImpl 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);
    }
}

사용자 정의 인터페이스 상속

스프링 데이터 리포지토리에 사용자 정의 인터페이스를 상속한다.

public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom {
	List<Member> findByUsername(String username);
}

동작 테스트

@Test
public void searchTest() {
    Team teamA = new Team("teamA");
    Team teamB = new Team("teamB");
    em.persist(teamA);
    em.persist(teamB);
    
    Member member1 = new Member("member1", 10, teamA);
    Member member2 = new Member("member2", 20, teamA);
    Member member3 = new Member("member3", 30, teamB);
    Member member4 = new Member("member4", 40, teamB);
    
    em.persist(member1);
    em.persist(member2);
    em.persist(member3);
    em.persist(member4);
    
    MemberSearchCondition condition = new MemberSearchCondition();
    condition.setAgeGoe(35);
    condition.setAgeLoe(40);
    condition.setTeamName("teamB");
    
    List<MemberTeamDto> result = memberRepository.search(condition);
    
    assertThat(result).extracting("username").containsExactly("member4");
}

참조
https://www.inflearn.com/course/querydsl-%EC%8B%A4%EC%A0%84/dashboard

profile
안녕하세요 백엔드 개발자입니다.

0개의 댓글