Querydsl 3가지 방법 중 제가 테스트를 해본 2가지 방법 모두 적용방법을 알아보겠습니다.
QuerydslRepositorySupport 상속받아서 사용
@Repository
public class StoreRepositorySupport extends QuerydslRepositorySupport {
private final JPAQueryFactory jpaQueryFactory;
private final EntityManager entityManager;
/**
* Creates a new {@link QuerydslRepositorySupport} instance for the given domain type.
*
* @param domainClass must not be {@literal null}.
* @param entityManager
*/
public StoreRepositorySupport(JPAQueryFactory jpaQueryFactory, EntityManager entityManager) {
super(Store.class);
this.jpaQueryFactory = jpaQueryFactory;
this.entityManager = entityManager;
}
public PageImpl<StoreVo> findStoresByNamePaging(String name, Pageable pageable) {
JPQLQuery<StoreVo> query = jpaQueryFactory // 1)
.select(Projections.fields(StoreVo.class,
store.id
, store.name
, store.address
))
.from(store)
.where(store.name.eq(name));
long totalCount = query.fetchCount(); // 2)
List<StoreVo> results = getQuerydsl().applyPagination(pageable, query).fetch(); // 3)
return new PageImpl<>(results, pageable, totalCount); // 4)
}
}
- JPQLQuery를 생성합니다.
- JPQLQuery로 TotalCount를 조회합니다.
- JPQLQuery로 데이터를 조회합니다.
- QuerydslRepositorySupport의 getQuerydsl() 메소드를 이용합니다.
- Pageable 객체의 page, limit, sort값을 적용합니다.
- 적용된 쿼리를 이용하여 데이터를 조회합니다.
- PageImpl 객체로 리턴합니다.
여기서 주의할 점은 Pageable의 page 값은 0부터 입니다.
전 1로 세팅해서 데이터가 왜 안나오는지 삽질을 1시간 넘게한 흑역사가 있습니다. 꼭 0부터 세팅해주세요.
Test 코드를 작성하여 실행하면 Success가 나오는 것을 확인할 수 있습니다.
@ActiveProfiles("local")
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class StoreRepositorySupportTest {
@Test
void querydsl_페이징처리() {
//given
final String name = "용태스토어";
Sort.Order order = Sort.Order.desc("id");
Sort sort = Sort.by(order);
Pageable pageable = PageRequest.of(0, 10, sort);
//when
PageImpl<StoreVo> result = storeRepositorySupport.findStoresByNamePaging(name, pageable);
//then
assertThat(result.getNumber()).isEqualTo(0);
assertThat(result.getTotalPages()).isEqualTo(1);
assertThat(result.getContent().size()).isEqualTo(1);
}
}
JpaRepository에서 상속받아 사용
구현 방법은 이 글에서 작성하지 않겠습니다. 궁금하신 분께서는 글 도입부의 지난글 링크를 참조해주세요.
Querydsl paging 처리 로직은 impl 클래스에 작성하였습니다. 간단하게 소스를 살펴보겠습니다.
import static com.example.querydsl.staff.entity.QStaff.staff;
@RequiredArgsConstructor // 의존성 주입
public class CustomizedStaffRepositoryImpl implements CustomizedStaffRepository {
private final JPAQueryFactory jpaQueryFactory;
public PageImpl<StaffVo> findStaffsByNamePaging(String name, Pageable pageable) {
JPQLQuery<StaffVo> query = jpaQueryFactory // 1)
.select(Projections.fields(StaffVo.class,
staff.id
, staff.age
, staff.name
))
.from(staff)
.where(staff.name.eq(name));
return pagingUtil.getPageImpl(pageable, query, Staff.class); // 2)
}
}
- JPQLQuery를 생성합니다.
- 이 방법은 QuerydslRespositorySupport 를 상속받지 않아 getQuerydsl 메서드를 사용할 수 없습니다. 그래서 동일한 기능을 하는 메서드를 유틸리티로 생성하였습니다.
공통메서드 PagingUtil을 살펴보겠습니다.
@Component
@RequiredArgsConstructor
public class PagingUtil {
private final EntityManager entityManager;
private Querydsl getQuerydsl(Class clazz) { // 1)
PathBuilder<Staff> builder = new PathBuilderFactory().create(clazz);
return new Querydsl(entityManager, builder);
}
public <T> PageImpl<T> getPageImpl(Pageable pageable, JPQLQuery<T> query, Class clazz) { // 2)
long totalCount = query.fetchCount();
List<T> results = getQuerydsl(clazz).applyPagination(pageable, query).fetch();
return new PageImpl<>(results, pageable, totalCount);
}
}
- QuerydslRepositorySupport 내부의 getQuerydsl과 동일하게 메서드를 생성하였습니다.
- getQuerydsl 메서드를 이용해서 PageImpl 객체를 생성하여 가져오는 코드입니다.
- Class 파라미터는 Entity 클래스를 넣어주세요.
Test 코드를 작성하여 실행하면 Success를 확인할 수 있습니다.
@ActiveProfiles("local")
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class StaffRepositoryTest {
@Test
void querydsl_페이징처리() {
//given
final String name = "임임용태";
Sort.Order order = Sort.Order.desc("id");
Sort sort = Sort.by(order);
Pageable pageable = PageRequest.of(0, 10, sort);
//when
PageImpl<StaffVo> staffsByNamePaging = staffRepository.findStaffsByNamePaging(name, pageable);
//then
assertThat(staffsByNamePaging.getNumber()).isEqualTo(0);
assertThat(staffsByNamePaging.getTotalPages()).isEqualTo(1);
assertThat(staffsByNamePaging.getContent().size()).isEqualTo(1);
}
}
728x90
'Study > 개발일지' 카테고리의 다른 글
[백엔드온라인TIL] Spring Test junit5 (56일차) (0) | 2023.08.14 |
---|---|
[백엔드스터디WIL]JPA no Creators, like default constructor, exist):cannot deserialize from Object value (no delegate- or property-based Creator(11주차) (0) | 2023.08.11 |
[백엔드온라인TIL] github Action과 ci/cd (54일차) (0) | 2023.08.10 |
[백엔드온라인TIL] JPA 엔티티에 json 타입지정하기 (53일차) (1) | 2023.08.09 |
[백엔드온라인TIL] AWS S3로 다중 이미지 업로드 (52일차) (0) | 2023.08.08 |