728x90
다양한 SQL 그룹 함수
- sum : 주어진 column의 합계를 계산한다.
- avg : 주어진 column의 평균을 계산한다.
- count : 개수를 센다
- group by : 주어진 column을 기준으로 grouping 한다. -> 함수형 프로그래밍의 groupby와 유사하다.
- order by : 주어진 column을 기준으로 정렬한다. -> 내림차순, 오름차순 지정할 수 있다.
애플리케이션 대신 DB로 기능 구현하기
UserLoanHistoryRepository
interface UserLoanHistoryRepository : JpaRepository<UserLoanHistory, Long> {
//...
fun countByStatus(status: UserLoanStatus): Long
}
BookService
@Transactional(readOnly = true)
fun countLoanedBook(): Int {
//기능은 같지만 내부 동작이 아예 다르다.
//1) 전체 데이터 쿼리 메모리 로딩 + size 2) count 쿼리 타입 변경
//2번 기능이 더 좋다고 생각한다 -> 데이터가 많아질수록.. OOM이 생길수 있다
return userLoanHistoryRepository.countByStatus(UserLoanStatus.LOANED).toInt() //숫자만 메모리에 올려 타입만 변경해준다
}
- 이전 방식과 다르게 DB에서 Count 쿼리를 한 결과를 가지고 와서 타입만 변환하여 리턴한다.
- 이전 기능에서는 전체 데이터를 쿼리로 가지고와 메모리에 로딩한 후, 애플리케이션에서 size를 측정하였고, 이번 방식은 DB에서 Count 쿼리를 바로 동작시켜 값만 받아와서 변환해준다.
- 2번째 방법이 좀 더 좋은 거 같다 -> 모든 데이터를 메모리에 올리게 되면 애플리케이션을 부하가 심해지고, 메모리가 full 될 수도 있다.
BookRepository
interface BookRepository : JpaRepository<Book, Long> {
//...
@Query("select new com.group.libraryapp.dto.book.request.BookStatResponse(b.type, COUNT(b.id)) from Book b " +
"group by b.type")
fun getStats(): List<BookStatResponse>
}
BookService
@Transactional(readOnly = true)
fun getBookStatistics(): List<BookStatResponse> {
return bookRepository.getStats()
}
- @Query를 사용해 JPQL을 작성할 수 있으며, 생성자를 통해 Projection을 지정할 수 있다
- 이때 반드시 dto는 풀 패키지 명을 적어야 한다.
- group by 함수를 사용해 type으로 grouping하여 count를 추려왔다
- 이전 방식보다 지금방식이 더 좋아 보인다 -> DB는 index를 걸거나 해서 최적화를 할 수 있기 때문이다
- 단, 반드시 지금 방식이 좋은 것은 아니기 때문에 상황에 따라 적절한 방식을 선택해서 진행하는 방식으로 하자
728x90
'실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기' 카테고리의 다른 글
| Ch04. 요구사항 추가(책 통계, QueryDSL) - QueryDSL 사용하기 (0) | 2022.11.08 |
|---|---|
| Ch04. 요구사항 추가(책 통계, QueryDSL) - QueryDSL 도입하기 (0) | 2022.11.08 |
| Ch04. 요구사항 추가(책 통계, QueryDSL) - 책 통계 테스트 코드와 리펙토링 (0) | 2022.11.07 |
| Ch04. 요구사항 추가(책 통계, QueryDSL) - 책 통계 요구사항 추가 (0) | 2022.11.07 |
| Ch03. 요구사항 추가(type, 대출현황) - N+1 문제와 SQL 조인을 통한 문제 해결(fetch join) (0) | 2022.11.06 |