Spring Data Jpa Custom Repository 적용하기

KHoney·2022년 8월 24일
0

Java

목록 보기
7/10
post-thumbnail

Spring Data Jpa 에서는 Custom Repository와 JpaRepository 상속 클래스에서 사용할수 있도록 지원하기 때문에 Querydsl 을 추가로 사용할 때 하나의 Repository로 JPARepository 와 Querydsl Repository를 상속하여 사용할 수 있다.

일종의 공식처럼 보면되는데,  Custom이 붙은 인터페이스를 상속한 Impl 클래스의 코드는 Custom 인터페이스를 상속한 JpaRepository에서도 사용할 수 있게된다.

Cutom 인터페이스에 함수를 추가한다.

public interface CodeRepositoryCustom {
    List<CodeVO> findAllPlantList();

    List<CodeVO> findProcessUnitByPlant(String plant);

    List<CodeVO> findReactorByPlantAndProcessUnit(String plant, String processUnit);
}

Impl 클래스에서 각 함수들을 정의해준다.

@RequiredArgsConstructor
public class CodeRepositoryImpl implements CodeRepositoryCustom {
    final JPAQueryFactory query;
    QCodeVO qCode = QCodeVO.codeVO;

    @Override
    public List<CodeVO> findAllPlantList() {
        return query
                .selectFrom(qCode)
                .where(qCode.parentId.eq(
                                selectParentId(CodeVO.ParentCode.PLANT.name()))
                )
                .fetch();
    }

    @Override
    public List<CodeVO> findProcessUnitByPlant(String plant) {
        if (plant == null)
            return null;
        return query
                .selectFrom(qCode)
                .where(qCode.parentId.eq(
                                (selectParentId(CodeVO.ParentCode.PROCESS.name())))
                        .and(qCode.plant.eq(plant))
                )
                .fetch();
    }

    @Override
    public List<CodeVO> findReactorByPlantAndProcessUnit(String plant, String processUnit) {
        if (plant == null || processUnit == null)
            return null;
        return query
                .selectFrom(qCode)
                .where(qCode.parentId.eq(
                        (selectParentId(CodeVO.ParentCode.REACTOR.name())))
                        .and(qCode.plant.eq(plant))
                        .and(qCode.processUnit.eq(processUnit))
                )
                .fetch();
    }
		// 많이 사용하는 서브쿼리는 따로 함수로 정의한다.
    private JPAQuery<UUID> selectParentId(String code) {
				QCodeVO qParentCode = new QCodeVO("parentCode");
        return query
                .select(qParentCode.id).from(qParentCode)
                .where(qParentCode.code.eq(code)
                        .and(qParentCode.parentId.isNull()));
    }
}

페이징이 필요한게 아니라면 QuerydslSupport 를 상속할 필요가 없다.

이제 코드를 CodeRepository 에서 쓸수 있도록 Custom Interface 를 상속해준다.

public interface CodeRepository extends JpaRepository<CodeVO, UUID>, CodeRepositoryCustom {
}

이제 CodeRepository 에서 기본적인 JpaRepository 함수와 더불어 Impl 에 정의된 Querydsl 함수들을 모두 사용할 수 있다!!

성공적인 테스트 결과

잘 적용된것을 볼 수 있다.

이런 구조를 만들어 놓으면 기본적인 작업과 Custom한 작업을 하나의 repository로 관리 할 수 있기 때문에 코드가 깔끔해지는 장점을 가질 수 있는게 체감이 된다.

profile
좋은 개발자가 되고싶은

0개의 댓글