일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- #내일배움캠프
- static
- 스파르타내일배움캠프TIL
- 변수의 다양성
- #스파르타내일배움캠프TIL
- KPT
- JVM
- 생성자
- Token
- 스레드
- 객체지향 언어
- Github_token
- diary
- 성장기록
- #스파르타내일배움캠프
- Git
- 클래스
- 회고록
- 메서드
- GitHub
- TiL_1st_0419
- 스파르타내일배움캠프
- 인스턴스
- 해우소
- Diary 해우소
- Java의 이점
- Java
- 내일배움캠프
- 포맷은 최후의 보루
- 감사기록
- Today
- Total
몬그로이
본인이 좋아요 표시한 게시글 - 모두 조회 - 페이징 본문
조건
페이징 처리(5개씩)
며칠 전 자바의 정석에서 상속이나 인터페이스를 활용한 메서드를 생성하는 예시를 보고 한 번쯤 사용해 보고 싶었는데
이번 강의에서도 이를 활용하고 있었기에 이번 개인 과제를 진행하면서 참고해서 적용해보기로 했다
다른 점이라면 지난 팀과제에 이어 개인과제를 진행하는 것이라 adapter가 추가되어 있어서 이것도 고려해야 한다는 점이겠다
강사님이 만들어 놓은 결과물을 면밀히 뜯어 보다가 새롭게 알게 된 것
interface 가 interface 를 상속받을 때 extends 를 사용하며,
interface 의 기능 중 하나라도 구현한다면 그 때 implements 를 사용한다
JpaRepository | ThanksQueryRepository |
ThanksRepository | |
ThanksQueryRepositoryImpl |
클래스인 ThanksQueryRepositoryImpl 과 인터페이스인 ThanksQueryRepository를 새로 생성한다
ThanksRepository 는 두 인터페이스 JpaRepository 와 ThanksQueryRepository 의 상속을 받고
ThanksQueryRepositoryImpl 은 ThanksQueryRepository 의 상속을 받는다
ThanksRepository 는 단순 CRUD 를 수행하도록 하고 (JpaRepository의 영향)
나머지는 ThanksQueryRepositoryImpl 에서 수행하도록 할 것이다
ThanksQueryRepositoryImpl 이 ThanksQueryRepository에서 정의해 둔 메서드를 완성할 것이므로
ThanksRepository 에서 ThanksQueryRepository 에서 정의된 메서드를 사용할 때
ThanksQueryRepositoyImpl 의 메서드가 호출될 것이다
여기에 ThanksAdapter도 ThanksRepository를 호출하도록 설정되어 있이므로
큰 흐름은 결국 ThanksRepository 가 담당하는 것이다
강사님의 코드를 면밀히 뜯어보다가 또 발견한 것들이 있다
바로, 검색 조건을 한 클래스에 모아 놓은 것
찾아보니 보통 Condition 의 줄임말인 Cond 를 붙인다고 한다
그리고 이게 뭐야? 싶은 것이 있었는데
query 를 '분리'해 놓은 것이었다
query 라고 하는 단순 메서드 라고 여겨서
반환값이 List나 collection 타입으로 나오지 않는 이유가 뭐지?
라고 한참 생각했는데 이리저리 지지고볶다보니
query를 분리한 것이었던 것이다
페이징 처리하는 부분은 따로 분리해 놓지 않고 그냥 추가해 놓으셔서 알아챌 수 있었다
아마 일부러 힌트를 남겨두신 것이 아닐까?
거기에 정렬하는 것도 따로 떨어뜨려 놓으셔서
나는 모두 메서드로 뺀 다음 연결시키고 싶어졌다
var query = query(thread, cond)
.offset(pageable.getOffset())
.limit(pageable.getPageSize());
query.orderBy(thread.mentions.any().createdAt.desc());
var threads = query.fetch();
여기의 모든 쿼리를 각 역할에 맞는 메서드로 빼고 한 줄로 연결시킬 심산이다
물론 내가 작성하고 있는 도움이 돼요 기능에 맞춰서 말이다
private <T> JPAQuery<T> query(Expression<T> expr, ThreadSearchCond cond) {
return jpaQueryFactory.select(expr)
강사님이 만들어 두신 메서드를 구경하다가
Expression<T> 는 의문에 둔 채로 이것저것 구글링한다고 돌아다니고 있었다
그러다가 발견한 것이 상위의 관계도인데, 거기에 Expression<T> 가 있어 갑자기 이해가 되었다
얼마 전에 상속을 공부한 덕에 이해를 할 수 있었다고 생각한다
실력 격차가 심한 코드를 뜯어보고 있자니 시간이 참 잘 간다
https://earth-95.tistory.com/116
queryDsl 을 이용한 페이징이 내 실력엔 아직 어렵워서 내일 마저 해보기로 했다
fetchResults() 기능이 Deprecated 된 바람에 페이징 처리를 따로 진행해 줘야 하는데
그 때 전체 페이지 수를 count 하는 절차가 필요하다
처음에 queryDSL 한 메서드로 정렬과 페이지 수 처리까지 하는 건 좋았는데
여러 메서드로 분리하려다 보니까 반환타입의 차이 때문에
세조각으로 나누는 것은 힘들다는 것을 깨달았다
List<Thanks> result = query(thanks, user)
.orderBy(thanks.userReviews.createdAt.desc())
.offset(pageable.getOffset())
.limit(PAGE_SIZE_FIVE)
.fetch();
여기에서 정렬과 페이징 설정도 떼어내고 싶었는데 그러지 못했다
구글링해 본 결과 데이터를 count 하여 페이징 상태로 return 하는 방법은 크게 두 가지였다
private JPAQuery<Long> countQuery(User user) {
return jpaQueryFactory
.select(Wildcard.count)
.from(thanks)
.where(userIdEq(user.getId()));
}
일단 이 메서드가 정의된 전제 하에서
1. count 를 Long 타입으로 반환받을 경우
long total = countQuery(user).fetch().get(0);
return PageableExecutionUtils.getPage(result, pageable, () -> total);
2. count 를 JPAQuery<Long> 타입으로 반환받을 경우
JPAQuery<Long> total = countQuery(user);
return PageableExecutionUtils.getPage(result, pageable, total::fetchCount);
'Dev입성기 > Dev 입성기_중기' 카테고리의 다른 글
나침반 (0) | 2024.07.04 |
---|---|
프로필 조회시 좋아요 수 필드 추가하기 (0) | 2024.07.04 |
단 건 조회 - 좋아요 count 추가를 위한 테이블 정리 (0) | 2024.07.04 |
핑계 (0) | 2024.07.03 |
모르겠다 진짜 (0) | 2024.07.03 |