반응형
Notice
Recent Posts
Recent Comments
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 덩크로우
- Python
- 파이썬
- Nike
- Dunk Low
- stockx.com
- 덩크 하이
- sacai
- 덩크 로우
- dunk high
- 주식공부
- 리액트
- 드로우
- 리눅스
- 자바스크립트
- Java
- JavaScript
- 발매예정
- GIT
- 제이쿼리
- oracle
- 코로나19
- 주식
- 나이키
- Linux
- draw
- 오라클
- dunklow
- jQuery
- react
Archives
- Today
- Total
Life goes slowly...
[JPA] JPA ExpressionUtils 서브쿼리로 연산방법 본문
728x90
반응형
ExpressionUtils로 산술 연산하기
❌ 잘못된 시도
ExpressionUtils.as(subQuery1, "a")
.subtract(ExpressionUtils.as(subQuery2, "b"));
-- ExpressionUtils는 계산용 API가 아니기 때문에 불가능
올바른 산술 연산 방법 (NumberExpression)
- 서브쿼리끼리 “계산”을 하려면, 각각을 JPAExpressions로 만들고, select 절에서는 ExpressionUtils.as로 alias를 주고, where/조건절에서는 서브쿼리 Expression을 그냥 연산에 넣어서 사용
기본 개념 정리
- Querydsl(JPA)에서 서브쿼리는 select 절, where 절에서만 사용 가능.
- select 절:
- ExpressionUtils.as(JPAExpressions.select(...), "별칭") 으로 DTO 필드에 매핑.
- where 절:
- JPAExpressions.select(...) 를 바로 비교/연산에 사용 (ExpressionUtils.as 필요 없음).
패턴 요약
- “서브쿼리 뽑아서 DTO 필드로 받고 싶다”
- ExpressionUtils.as(JPAExpressions.select(...), "필드명").
- “where 절에서 서브쿼리와 컬럼/서브쿼리 비교하고 싶다”
- 컬럼.gt(JPAExpressions.select(...)), 컬럼.between(서브1, 서브2).
- “서브쿼리 둘을 계산한 결과를 select로 받고 싶다”
- NumberExpression sub1 = JPAExpressions.select(...);
- NumberExpression sub2 = JPAExpressions.select(...);
- ExpressionUtils.as(sub1.subtract(sub2), "필드명").
select 절에서 “서브쿼리끼리 연산 결과” 뽑기
두 서브쿼리 결과의 차이/합 등을 DTO로 받고 싶다면, 먼저 연산 Expression을 만든 뒤 그걸 ExpressionUtils.as로 감쌉니다.
NumberExpression<Integer> minPrice = JPAExpressions
.select(orderSub.price.min())
.from(orderSub);
NumberExpression<Integer> maxPrice = JPAExpressions
.select(orderSub.price.max())
.from(orderSub);
// max - min 값(스프레드)을 DTO에 담기
List<PriceSpreadDto> result = queryFactory
.select(Projections.fields(PriceSpreadDto.class,
ExpressionUtils.as(
maxPrice.subtract(minPrice), // 서브쿼리끼리 연산
"spread"
)
))
.from(order)
.fetch();
select 절: 서브쿼리 뽑고, 별칭 주기
- 첫 번째 인자: JPAExpressions.select(...) 로 만든 서브쿼리 Expression.
- 두 번째 인자: DTO의 필드명 "studentCount".
이 패턴을 반복해서 여러 서브쿼리 값을 DTO에 동시에 넣을 수 있습니다
public List<AcademyStudentCountDto> findAllStudentCount() {
return queryFactory
.select(Projections.fields(AcademyStudentCountDto.class,
academy.name.as("academyName"),
ExpressionUtils.as( // 서브쿼리 결과에 별칭
JPAExpressions
.select(student.id.count())
.from(student)
.where(student.academy.eq(academy)),
"studentCount"
)
))
.from(academy)
.fetch();
}
where 절: 서브쿼리끼리 연산(>, <, between 등)
where 절에서는 서브쿼리 Expression끼리 바로 연산하면 됩니다.
1. 컬럼 vs 서브쿼리
board.views 와 JPAExpressions.select(...).from(...) 를 gt, goe, lt 등으로 비교.
// 조회수 > 전체 평균 조회수
List<Board> result = queryFactory
.selectFrom(board)
.where(board.views.gt(
JPAExpressions
.select(subBoard.views.avg())
.from(subBoard)
))
.fetch();
2. 서브쿼리 vs 서브쿼리 (예: between)
서브쿼리 둘을 만들어서 between 등에 넣을 수 있습니다. (DB가 스칼라 서브쿼리 연산을 허용하면 사용 가능)
- between(lower, upper) 에 각각 서브쿼리 Expression을 그대로 넣는 방식입니다.
다른 예로 gt, lt, between, loe, goe 등 수치 연산 메서드에 서브쿼리들을 인자로 넘겨서 “서브쿼리 간 연산”을 표현할 수 있습니다.
NumberExpression<Integer> lower = JPAExpressions
.select(orderSub.price.min())
.from(orderSub);
NumberExpression<Integer> upper = JPAExpressions
.select(orderSub.price.max())
.from(orderSub);
List<Order> result = queryFactory
.selectFrom(order)
.where(order.price.between(lower, upper))
.fetch();
728x90
반응형
'프로그래밍 > Java' 카테고리의 다른 글
| [JPA] JPA에서 JpaRepository를 사용하여 쿼리 작성 방법 (0) | 2026.01.31 |
|---|---|
| [JPA] JPA - ExpressionUtils / 서브쿼리 (0) | 2026.01.30 |
| [JPA] JPA + Querydsl 코드 작성방법 (0) | 2026.01.29 |
| [JPA]JPA 로 개발하면서 자주 하는 실수 Top 5 (0) | 2026.01.27 |
| [JPA] JPA 핵심 개념 5가지!!! (0) | 2026.01.26 |
| [JPA] 초보자가 쉽게 이해하는 JPA 동작구조 (0) | 2026.01.25 |
| [JPA] 초보자가 쉽게 이해하는 Spring Data JPA 설명 (3) | 2026.01.24 |
| [Java] 자바에서 객체 정렬하기 - Comparable, Comparator (0) | 2020.10.17 |
Comments