Search
〰️

사용자 정의 Repository (Spring Data JPA + Querydsl)

사용자 정의 리포지토리 구성

MemberRepositoryCustom (명명 규칙 없음) Interface
→ 구현체로 MemberRepositoryImpl (명명 규칙 있음, Repository명 + Impl)
1.
사용자 정의 인터페이스 작성
public interface MemberRepositoryCustom { List<MemberTeamDto> search(MemberSearchCondition condition); }
Java
복사
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.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 hasText(username) ? member.username.eq(username) : null; } private BooleanExpression teamNameEq(String teamName) { return 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; } }
Java
복사
3.
스프링 데이터 리포지토리에서 사용자 정의 인터페이스 상속
public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom { //select m from Member m where m.username = ? List<Member> findByUsername(String username); }
Java
복사
Repository가 공용성이 없고, API나 화면에 종속된 경우 아래와 같이 조회용 Repository로 별도 분리하여 설계상 유연성을 높인다.
@Repository public class MemberQueryRepository { private final JPAQueryFactory queryFactory; public MemberQueryRepository(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 hasText(username) ? member.username.eq(username) : null; } private BooleanExpression teamNameEq(String teamName) { return 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; } }
Java
복사