[QueryDSL] Expressions.dateTemplate로 SQL 구문 만들기

2025. 9. 22. 09:20·Development/Spring

 

QueryDSL로 날짜별 생성된 데이터를 세는 쿼리를 구현했다.

그런데 내가 생각한 것과 데이터 개수가 다르게 나오는 것이다...

(왜그럴까)


1. 문제 상황

Tuple results = queryFactory.select(qStatsTable.regDt, qStatsTable.count()) 
                            .from(qStatsTable) 
                            .orderBy(qStatsTable.regDt.desc()) 
                            .groupBy(qStatsTable.regDt) 
                            .limit(1) 
                            .fetchOne();

stats_table에서 reg_dt를 기준으로 그룹화하여 내림차순으로 정렬한 뒤 select 하는 QueryDSL이다.

reg_dt는 등록일자를 의미하는 컬럼인데 내가 생각한 결과는 날짜별로 count 개수를 세는 것이다.

 

SELECT reg_dt, COUNT(*) 
FROM stats_table 
GROUP BY reg_dt 
ORDER BY reg_dt DESC 
LIMIT 1;

QueryDSL을 쿼리문으로 바꾼 뒤 실행한 결과는 다음과 같았다.

이 결과가 나온 이유는 reg_dt는 TimeStamp로 정의되어 있기 때문에

초단위 시간까지 일치하는 reg_dt끼리 그룹화되어버린 것이다.

내가 원하는 결과는 reg_dt가 일 단위까지 끊어서 그룹화 하는 것이었다.


2. 해결 방법

그래서 수정한 쿼리문은 다음과 같다.

SELECT DATE(reg_dt) AS reg_dt, COUNT(*) 
FROM stats_table 
GROUP BY DATE(reg_dt) 
ORDER BY reg_dt DESC 
LIMIT 1;

 

reg_dt를 DATE로 감싸면 TimeStamp였던 형식을 Date 형식으로 변환하면서,

내가 원하는 일 단위 기준의 데이터 개수를 얻게 되었다!

 

자 이렇게 쿼리문으로 어떻게 짜야 하는지 감을 잡았으니 이제 QueryDSL에 적용해보자.

 

다양한 방법이 있곘지만 내가 사용하고 있는 데이터베이스는 Cubrid(큐브리드)이기 때문에,

(큐브리드가 지원할 수 있는) Expressions.dateTemplate을 이용하여 SQL 표현식을 작성할 수 있다.

 

Expressions.dateTemplate는 QueryDSL에서 날짜 형식을 지정하여 SQL 구문을 작성할 때 사용한다.

기본적인 형식은 이렇게 생겼다.

Expressions.dateTemplate(Date.class, "DATE({0})", qEntity.dateField)

1) 타입(Date.class) : 반환될 타입을 지정한다. TimeStamp -> Date 변환이 필요하면 Date.class를, TimeStamp -> String 변환이 필요하면 String.class를 입력하면 된다.

2) 패턴("DATE({0})") : 날짜 형식을 지정하는 템플릿 문자열이다. DATE 함수를 통해 {0}에는 qEntity.dateField가 들어간다. 

3) 값(qEntity.dateField) : 템플릿에서 사용될 값들을 전달한다.

 

이렇게 하면 시간 부분은 제외한 날짜만 추출할 수 있다.

예를 들어, 2025-09-15 12:30:45 에서 2025-09-15 만 추출할 수 있다.

 

날짜 형식을 DATE_FORMAT을 이용하여 직접 지정할 수도 있다.

Expressions.dateTemplate(Date.class, "DATE_FORMAT({0}, {1})", qEntity.dateField, "yyyy-MM-dd")

 

Query문으로 돌아가는 걸 확인했으니 QueryDSL에 적용시켜보자.

Tuple results = queryFactory.select(qStatsTable.regDt, qStatsTable.count())
                    .from(qStatsTable)
                    .groupBy(Expressions.dateTemplate(String.class, "DATE({0})", qStatsTable.regDt))
                    .orderBy(qStatsTable.regDt.desc())
                    .limit(1)
                    .fetchOne();

select 조건은 유지한채로 groupBy 문을 바꿔주었다.

기존에 qStatsTable.regDt 기준에서 qStatsTable.regDt을 DATE 형식으로 변환한 형태로 바꿔주었다.


3. 주요 Expressions 종류

1) Expressions.constant()

- 상수 값을 쿼리에서 사용할 때 사용한다.

Expressions.constant("Hello")

2) Expressioins.template()

- 템플릿 문자열을 이용하여 표현식을 생성한다.

Expressions.template(String.class, "CONCAT({0}, {1})", qEntity.firstName, qEntity.lastName)

3) Expressions.dateTemplate()

- 날짜 형식을 지정할 때 사용한다.

Expressions.dateTemplate(Date.class, "DATE_FORMAT({0}, {1})", qEntity.dateField, "yyyy-MM-dd")

4) Expressions.booleanTemplate()

- Boolean 타입을 처리할 수 있는 템플릿 표현식을 생성한다.

Expressions.booleanTemplate("{0} = {1}", qEntity.status, 1)

5) Expressions.numberTemplate()

- 숫자 타입 표현식을 생성할 때 사용한다.

Expressions.numberTemplate(Integer.class, "{0} + {1}", qEntity.num1, qEntity.num2)

6) Expressions.stringTemplate()

- 문자열 타입 표현식을 생성할 때 사용한다.

Expressions.stringTemplate("CONCAT({0}, {1})", qEntity.firstName, qEntity.lastName)

7) Expressions.path()

- Path 객체를 생성할 때 사용한다.

Expressions.path(String.class, "name")

8) Expressions.predicate()

- Predicate 객체를 생성할 때 사용한다.

Expressions.predicate(Ops.EQ, qEntity.status, 1)

저장할 때 Timestamp로 저장했기 때문에 groupBy도 초 단위로 그룹화하는 것을 놓쳤었다.

Expressions을 활용해서 다양한 조건을 가지고 있는 변수를 다룰 수 있었다.

 

728x90
저작자표시 비영리 변경금지 (새창열림)

'Development > Spring' 카테고리의 다른 글

[Apache POI] Iterator로 읽은 빈 셀 CellType.BLANK로 예외처리하기  (0) 2025.09.16
[Apache POI]Java에서 이미지를 포함한 Excel 파일 생성하기  (5) 2025.08.08
[SpringBoot] select 쿼리문에서 update가 일어났던 이유  (1) 2025.06.18
'Development/Spring' 카테고리의 다른 글
  • [Apache POI] Iterator로 읽은 빈 셀 CellType.BLANK로 예외처리하기
  • [Apache POI]Java에서 이미지를 포함한 Excel 파일 생성하기
  • [SpringBoot] select 쿼리문에서 update가 일어났던 이유
iihye_
iihye_
  • iihye_
    hye-log
    iihye_
    • 분류 전체보기 (296)
      • Development (19)
        • Spring (4)
        • Python (5)
        • React (4)
        • Next.js (1)
        • JavaScript (4)
        • CSS (1)
      • Infra (15)
        • Docker (1)
        • Jenkins (2)
        • Nginx (3)
        • JBoss (1)
        • Windows (3)
        • Linux (3)
        • Kafka (2)
      • Database (1)
        • MongoDB (1)
      • Tools (2)
        • Git (0)
        • Github (1)
        • Document (1)
      • CodingTest (125)
        • Programmers (38)
        • Baekjoon (52)
        • SWEA (27)
        • Jungol (4)
        • Codetree (1)
        • Goorm (3)
      • Education (99)
        • SSAFY 10기 (5)
        • AI Tech 4기 (94)
      • NomadCoder (35)
        • (JS)크롬 앱 만들기 (35)
      • Notice (0)
  • 링크

    • Github
  • 인기 글

  • 최근 글

  • 전체
    오늘
    어제
  • hELLO· Designed By정상우.v4.10.5
iihye_
[QueryDSL] Expressions.dateTemplate로 SQL 구문 만들기
상단으로

티스토리툴바