jpaQuery
.selectOne()
.from(테이블명)
.where(
조건
).fetchFirst() != null
-> 특정 조건에 해당하는 열을 가져오는데, 1 로 가져옴
-> 있을 경우 1이 리턴, 없으면 null이 리턴 됨
-> != null 로 참/거짓 값을고 변환하여 리턴
override fun findQById(
id: Long,
pageable: Pageable
): Page<Member> {
val member = QMember.member
//content
val result =jpaQuery
.selectFrom(member)
.where(조건)
.offset(pageable.offset) //시작
.limit(pageable.pageSize.toLong()) //끝
.fetch()
//total count
val totalCount= jpaQuery
.select(member.count())
.from(member)
.where(조건)
.fetchOne() ?: 0L
return PageImpl(result, pageable, totalCount)
}
리턴값이 Page라 조회가 2번 필요하다. (데이터랑, 페이지 관련 메타데이터)
+) JPA로 페이징 쓰기
fun findById(Id: Long, pageable: Pageable): Page<엔티티명> 끝.
오래 걸릴 수도 있고, 비효율적이다.
그래서 PageableExecutionUtils을 사용한다. 이러면 이제 필요할 때만 조회를 할 수 있다.
PageableExecutionUtils.getPage(조회한 데이터,pageable){totalCount 구하는 쿼리}
override fun findQByIdDesc(id: Long): List<Member> {
val member = QMember.member
return jpaQuery
.selectFrom(member)
.where(조건)
.orderBy(member.id.desc())
.fetch()
}
근데 사실 orderBy(member.id.desc()) 이건 OrderSpecifier를 받는 거라 직접 member.id.desc() 이렇게 적지 말고 따로 선언 해서 넣을 수 있긴하다.
-> .orderBy(member.id.desc()) 여기에 어떤 걸 기준으로 오름차순/내림차순 할 건지 정함
정렬을 pageable에 다 넣고 할 수도 있다.
val pageable = PageRequest.of(
0, 2, //오프셋과 페이지 사이즈
Sort.by("id").descending()
.and(Sort.by("username").ascending())
)
그리고 이걸로 조회도 가능
override fun findQByID(
Id: Long,
pageable: Pageable
): Page<Member> {
val member = QMember.member
// content 쿼리
val query = jpaQuery
.selectFrom(member)
.where(조건)
//정렬 기준을 정해줌
pageable.sort.forEach { order ->
when(order.property){
"id" -> query.orderBy(if(order.isAscending) member.id.asc() else member.id.desc())
"nickname" -> query.orderBy(if(order.isAscending) member.nickname.asc() else member.nickname.desc())
"username" -> query.orderBy(if(order.isAscending) member.username.asc() else member.username.desc())
}
}
//마저 쿼리
val content = query
.offset(pageable.offset)
.limit(pageable.pageSize.toLong())
.fetch()
//리턴
return PageableExecutionUtils.getPage(content, pageable) {
jpaQuery
.select(member.count())
.from(member)
.where(member.username.contains(username))
.fetchOne() ?: 0L
}
}
빌더를 이용해서 조건을 추가해서 검색하기도 가능하다.
val builder = BooleanBuilder()?.apply {
//검색 타입에 따라 어디서 검색할지 넣기
when(kwType){
"USERNAME" -> this.and(member.username.contains(kw))
"NICKNAME" -> this.and(member.nickname.contains(kw))
"ALL" -> {
this.and(member.username.contains(kw).or(
member.nickname.contains(kw)
))
}
}
}
이후 where()에 builder 넣으면 됨