본문 바로가기

개인적으로 공부한 것을 정리해 놓은 블로그입니다 틀린 것이 있으면 댓글 부탁 드립니다!


JPA/QueryDSL

QueryDSL 공부 10 - Spring data JPA 에서 QueryDsl활용

반응형

Spring data JPA는 인터페이스로 동작하기 때문에  직접 구현 코드를 작성해서 사용하려면 

 

사용자정의 인터페이스를 만들어 구현해야한다.

 

 

MemberRepository

 

package com.querydsl.study.repository;

import com.querydsl.study.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface MemberRepository extends JpaRepository<Member,Long> ,MemberRepositoryCustom{

    List<Member> findByUsername(String username);

}

 

먼저 Spring data JPA 를 구현할 repository를 인터페이스로 만들고 JpaRepository와

사용자가 정의한 Repository를 상속받았다 (뒤에 설명)

 

queryDsl을 사용하거나 JPQL로 직접 짠 코드를 사용하고 싶다면  사용자 정의 리파리토리 인터페이스를 만들어 주면된다 .

 

MemberRepositoryCustom

 

 

public interface MemberRepositoryCustom {
    List<MemberTeamDto> search(SearchCond searchCond);
}

 

간단하게 이전 시간에 공부했던 동적쿼리 메서드를 구현 해보려 한다.

 

다음으론 위의 인터페이스를 구현할 구현 클래스를 만들어 준다 .

 

MemberRepositoryImpl

 

 

package com.querydsl.study.repository;

import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.JPQLQueryFactory;

import com.querydsl.study.dto.MemberTeamDto;
import com.querydsl.study.dto.QMemberTeamDto;
import com.querydsl.study.dto.SearchCond;
import lombok.RequiredArgsConstructor;

import java.util.List;

import static com.querydsl.study.domain.QMember.member;
import static com.querydsl.study.domain.QTeam.team;
import static org.springframework.util.StringUtils.hasText;

@RequiredArgsConstructor
public class MemberRepositoryImpl implements MemberRepositoryCustom{

    private final JPQLQueryFactory queryFactory;

    @Override
    public List<MemberTeamDto> search(SearchCond cond) {
        return queryFactory
                .select(new QMemberTeamDto(
                        member.id.as("memberId"),
                        member.age,
                        member.username,
                        team.name.as("teamName")
                ))
                .from(member)
                .leftJoin(member.team , team)
                .where(
                        usernameEq(cond.getUsername()),
                        teamNameEq(cond.getTeamName()),
                        ageLoe(cond.getAgeLoe()),
                        ageGoe(cond.getAgeGoe())
                )
                .fetch();
    }

    private BooleanExpression ageGoe(Integer ageGoe) {
        return ageGoe != null ? member.age.goe(ageGoe) : null;
    }

    private BooleanExpression ageLoe(Integer ageLoe) {
        return ageLoe != null ? member.age.goe(ageLoe):null;
    }

    private BooleanExpression teamNameEq(String teamName) {
        return hasText(teamName) ? team.name.eq(teamName):null;
    }

    private BooleanExpression usernameEq(String username) {
        return hasText(username) ? member.username.eq(username):null;
    }
}

 

검색조건에 따라 동작하는 동적쿼리를 생성하는 queryDsl코드이다. 

사용자 정의 인터페이스인 ( MemberRepositoryCustom )의 구현체이다.

 

1. 중요한 것은 구현하는 클래스 ( MemberRepositoryImpl ) 와 

2. 사용자 정의 인터페이스 ( MemberRepositoryCustom ) 를

3. 상속받아 해당 구현 클래스를 사용하게 되는 리파지토리( MemberRepository ) 

 

1번과 3번의 이름이 일치해야 스프링이 인식하여 관리해준다.  

구현 클래스는 사용하는 리파지토리의 이름에 Impl을 붙혀 준다고 생각하면된다. 

 

그림으로 보면 아래와 같다

 

 

 

 

직접 쳐봐서 이해하는게 이해가 잘될 것 같다. 

 

Spring data JPA 를 사용하면서 사용자가 직접 코드를 작성하여 사용하고 싶을때는 위처럼 사용할 수 있다. 

하지만 위의 방법만 있는 것은 아니다. 상황에 따라 화면에 특화된 코드라면 그냥 화면용

Repository (JPARepository가 아닌) 를 새로 만들어 주입 받아 사용하는 것도 방법이다 .

 

상황에 맞게 유연하게 사용해야겠다.

반응형