Spring/Querydsl
Querydsl - Spring Data JPA와 QueryDSL
jddng
2022. 3. 26. 21:10
728x90
반응형
Spring Data JPA와 QueryDSL
Spring Data JPA를 사용할 때 QueryDSL을 사용하기 위해선 사용자 정의 리포지토리와 구현체를 만들어 상속받아야 한다.
QueryDSL을 사용하기 위한 순서
JpaRepository를 상속받는 인터페이스 생성
- Spring Data JPA에서 제공하는 JpaRepository 인터페이스를 상속받는 인터페이스 생성한다.
public interface MemberRepository extends JpaRepository<Member, Long> {
}
사용자 정의 인터페이스 생성
- QueryDSL을 사용하기 위해 필요한 인터페이스 생성
public interface MemberRepositoryCustom {
List<MemberTeamDto> search(MemberSearchCondition condition); // (1)
}
- (1) : QueryDSL로 구현할 메서드 작성
사용자 정의 인터페이스 구현체 생성
- 사용자 정의 인터페이스의 메서드를 오버라이딩하여 QueryDSL 사용
@RequiredArgsConstructor
public class MemberRepositoryImpl implements MemberRepositoryCustom{
private final JPAQueryFactory queryFactory; // (1)
@Override
public List<MemberTeamDto> search(MemberSearchCondition condition) { // (2)
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 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;
}
}
- (1) : QueryDSL을 사용하기위한 팩토리 클래스 주입
- (2) : 인터페이스 메서드를 오버라이드하여 동적 쿼리 구현
Spring Data Repository에 사용자 정의 인터페이스 상속
public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom {
}
사용자 정의 리포지토리 동작 테스트
@Autowired
EntityManager em;
@Autowired
MemberRepository memberRepository;
@Test
@DisplayName("사용자 정의 리포지토리 테스트")
public void searchTest2() {
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> results = memberRepository.search(condition); // (1)
assertThat(results).extracting("username").containsExactly("member4");
}
- 사용자 정의 리포지토리 메서드 사용
728x90
반응형