MemberRepository 추가
public interface MemberRepository extends JpaRepository<Member,Long> {
List<Member> findByUsername(String username);
}
기본적으로 주어지는 JpaRepository에 있는 findAll(), findById() 의 경우 사용하는데 아무 지장 없지만 우리가 만들었던 querydsl 전용 기능인 search() 는 작성할 수없다.
이미지로 이해하는게 빠르기 때문에 이미지를 가져왔다.
사용자 커스텀 인터페이스를 작성해서 내가 추가할 기능이 뭔지 적어준다.
public interface MemberRepositoryCustom {
List<MemberTeamDto> search(MemberSearchCond cond);
}
적어둔 인터페이스를 구현할 구현부를 따로 만들어준다.
public class MemberRepositoryImpl implements MemberRepositoryCustom {
private final JPAQueryFactory queryFactory;
public MemberRepositoryImpl(EntityManager em) {
this.queryFactory = new JPAQueryFactory(em);
}
@Override
public List<MemberTeamDto> search(MemberSearchCond cond) {
return queryFactory
.select(new QMemberTeamDto(
member.id,
member.username,
member.age,
team.id,
team.name
))
.from(member)
.leftJoin(member.team, team)
.where(usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.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 ? null : member.age.goe(ageGoe);
}
private BooleanExpression ageLoe(Integer ageLoe) {
return ageLoe == null ? null : member.age.loe(ageLoe);
}
private BooleanExpression ageBetween(int ageLoe, int ageGoe) {
return ageGoe(ageGoe).and(ageLoe(ageLoe));
}
}
public interface MemberRepository extends JpaRepository<Member,Long>,MemberRepositoryCustom {
List<Member> findByUsername(String username);
}
이렇게 하면 search 함수를 사용할수 있게된다.
@Override
public Page<MemberTeamDto> searchPageComplex(MemberSearchCond cond, Pageable pageable) {
List<MemberTeamDto> content = queryFactory
.select(new QMemberTeamDto(
member.id,
member.username,
member.age,
team.id,
team.name
))
.from(member)
.leftJoin(member.team, team)
.where(usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.getAgeLoe()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
Long total = queryFactory
.select(member.count())
.from(member)
.leftJoin(member.team, team)
.where(usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.getAgeLoe()))
.fetchOne();
return new PageImpl<>(content,pageable,total);
}
pageableExecutionUtils.getPage()를 통한 최적화
Count 쿼리가 생략 가능한 경우 생략해서처리
CountQuery 추가 진행
@Override
public Page<MemberTeamDto> searchPageComplex(MemberSearchCond cond, Pageable pageable) {
List<MemberTeamDto> content = queryFactory
.select(new QMemberTeamDto(
member.id,
member.username,
member.age,
team.id,
team.name
))
.from(member)
.leftJoin(member.team, team)
.where(usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.getAgeLoe()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// Long total = queryFactory
// .select(member.count())
// .from(member)
// .leftJoin(member.team, team)
// .where(usernameEq(cond.getUsername()),
// teamNameEq(cond.getTeamName()),
// ageGoe(cond.getAgeGoe()),
// ageLoe(cond.getAgeLoe()))
// .fetchOne();
//countQuery 추가
JPAQuery<Member> countQuery = queryFactory
.select(member)
.from(member)
.leftJoin(member.team, team)
.where(usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.getAgeLoe()));
// return new PageImpl<>(content,pageable,total);
return PageableExecutionUtils.getPage(content,pageable,countQuery::fetchCount);
}