QueryDSL - 사용자 정의 Repository

목차

참고

사용자 정의 Repository 사용법

  1. 사용자 정의 인터페이스 작성
  2. 사용자 정의 인터페이스 구현
  3. 스프링 데이터 Repository 에 사용자 정의 인터페이스 상속

1. 사용자 정의 인터페이스 작성

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

2. 사용자 정의 인터페이스 구현

public class MemberRepositoryImpl implements MemberRepositoryCustom{

private final JPAQueryFactory queryFactory;

public MemberRepositoryImpl(EntityManager em){
this.queryFactory = new JPAQueryFactory(em);
}

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 StringUtils.hasText(username) ? member.username.eq(username) : null;
}
private BooleanExpression teamNameEq(String teamName){
return StringUtils.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;
}
}

3. 스프링 데이터 Repository 에 사용자 정의 인터페이스 상속

MemberRepository 인터페이스는 JPA 에서 기본적으로 제공하는 JpaRepository 와 사용자가 정의한 MemberRepositoryCustom 두개의 인터페이스를 상속 받는다.

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

MemberRepository 상속 관계

@Test
public void searchTest3(){
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");
}
Share