스프링 데이터 JPA - MemberRepository 생성
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsername(String username);
}
- Querydsl 전용 기능인 회원 search를 작성할 수 없다. → 사용자 정의 리포지토리 필요
사용자 정의 리포지토리 사용법
- 사용자 정의 인터페이스 작성
- 사용자 정의 인터페이스 구현
- 스프링 데이터 리포지토리에 사용자 정의 인터페이스 상속
사용자 정의 리포지토리 구성

1. 사용자 정의 인터페이스 작성
public interface MemberRepositoryCustom extends MemberRepository{
List<MemberTeamDto> search(MemberSearchCondition condition);
}
2. 사용자 정의 인터페이스 구현
public class MemberRepositoryImpl implements MemberRepositoryCustom {
private final JPAQueryFactory queryFactory;
public MemberRepositoryImpl(EntityManager em) {
this.queryFactory = new JPAQueryFactory(em);
}
@Override
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 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 age) {
return age != null ? member.age.goe(age) : null;
}
private BooleanExpression ageLoe(Integer age) {
return age != null ? member.age.loe(age) : null;
}
}
3. 스프링 데이터 리포지토리에 사용자 정의 인터페이스 상속
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 = memberJpaRepository.searchByBuilder(condition);
Assertions.assertThat(result).extracting("username").containsExactly("member4");
}
'QueryDSL' 카테고리의 다른 글
[QueryDSL] 스프링 데이터 페이징와 Querydsl 페이징 연동 (0) | 2025.02.20 |
---|---|
[QueryDSL] 순수 JPA와 QueryDSL (0) | 2025.02.19 |
[QueryDSL] 수정, 삭제 벌크 연산, SQL function 호출 (0) | 2025.02.19 |
[QueryDSL] 동적 쿼리 (0) | 2025.02.19 |
[QueryDSL] 프로젝션과 결과 반환 (0) | 2025.02.19 |