Querydsl - Data Jpa와 Querydsl

Seongjin Jo·2022년 12월 29일
0

Querydsl

목록 보기
7/8

✔ data jpa


public interface MemberRepository extends JpaRepository<Member,Long> {
    List<Member> findByUsername(String username);
}

✔ 사용자 정의 리포지토리


사용자 정의 리포지토리 사용법

  • 1.사용자 정의 인터페이스 작성
  • 2.사용자 정의 인터페이스 구현
  • 3.스프링 데이터 리포지토리에 사용자 정의 인터페이스 상속

1.Custom 인터페이스 생성

public interface MemberRepositoryCustom {
    List<MemberTeamDto> search(MemberSearchCondition condition0);
	}

2.Custom 인터페이스 구현 (MemberRepositoryImpl)

Impl을 붙일때는 데이터jpa 인터페이스명이랑 똑같은 이름에다 + Impl해줘야함

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();
    }

파라미터 메서드 생략

3. 스프링 데이터 리포지토리에 사용자 정의 인터페이스 상속

public interface MemberRepository extends JpaRepository<Member,Long>, MemberRepositoryCustom{
    List<Member> findByUsername(String username);
}

✔ 데이터 페이징 활용 - Querydsl 페이징 연동


data jpa를 활용한 querydsl 페이징 기본 방식

1.자바 코드를 이용한 total 계산 후 PageImpl return

@Override
    public Page<MemberTeamDto> searchPageSimple(MemberSearchCondition condition, Pageable pageable) {
        List<MemberTeamDto> result = 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())
                )
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

        //자바코드로 결과값 사이즈
        long total = result.size();
        //pageable을 이용한 page객체 생성 후 리턴
       return new PageImpl<>(result, pageable, total);
    }

2.count 쿼리 따로 생성 후 PageImpl return

    @Override
    public Page<MemberTeamDto> searchPageComplex(MemberSearchCondition condition, Pageable pageable) {
        List<MemberTeamDto> result = 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())
                )
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

        //fetch().size()로 count쿼리를  따로 파는 방식
        int totalSize = queryFactory
                .select(member)
                .from(member)
                .leftJoin(member.team, team)
                .where(usernameEq(condition.getUsername()),
                        teamNameEq(condition.getTeamName()),
                        ageGoe(condition.getAgeGoe()),
                        ageLoe(condition.getAgeLoe())
                )
                .fetch().size();

        //count 쿼리 최적화 방식
        //count 쿼리가 생략 가능한 경우 생략해서 처리
        //페이지 시작이면서 컨텐츠 사이즈가 페이지 사이즈보다 작을 때
        //마지막 페이지 일 때 (offset + 컨텐츠 사이즈를 더해서 전체 사이즈 구함)
        JPAQuery<Member> countQuery = queryFactory
                .select(member)
                .from(member)
                .leftJoin(member.team, team)
                .where(usernameEq(condition.getUsername()),
                        teamNameEq(condition.getTeamName()),
                        ageGoe(condition.getAgeGoe()),
                        ageLoe(condition.getAgeLoe()));
        return PageableExecutionUtils.getPage(result, pageable,() -> countQuery.fetch().size());
//      return new PageImpl<>(result,pageable,totalSize);
    }

3.count쿼리 최적화 방식

  • PageableExecutionUtils.getPage()로 최적화
  • count 쿼리가 생략 가능한 경우 생략해서 처리
  • 페이지 시작이면서 컨텐츠 사이즈가 페이지 사이즈보다 작을 때
  • 마지막 페이지 일 때 (offset + 컨텐츠 사이즈를 더해서 전체 사이즈 구함)
    @Override
    public Page<MemberTeamDto> searchPageComplex(MemberSearchCondition condition, Pageable pageable) {
        List<MemberTeamDto> result = 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())
                )
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

        JPAQuery<Member> countQuery = queryFactory
                .select(member)
                .from(member)
                .leftJoin(member.team, team)
                .where(usernameEq(condition.getUsername()),
                        teamNameEq(condition.getTeamName()),
                        ageGoe(condition.getAgeGoe()),
                        ageLoe(condition.getAgeLoe()));
                        
        return PageableExecutionUtils.getPage(result, pageable,() -> countQuery.fetch().size());
    }

4.Controller 개발

	@GetMapping("/v2/members")
    public Page<MemberTeamDto> searchMemberV2(MemberSearchCondition condition, Pageable pageable) {
        return memberRepository.searchPageSimple(condition,pageable);
    }

    @GetMapping("/v3/members")
    public Page<MemberTeamDto> searchMemberV3(MemberSearchCondition condition, Pageable pageable) {
        return memberRepository.searchPageComplex(condition,pageable);
    }

pageIndex는 0부터 시작한다. 2페이지이면서 페이지 크기는 5를 조회 했을때 member10~member14 까지 조회가 된다.

0개의 댓글