목표
JPA의 select 구문에 내장함수(SQL function)이나 상수값을 넣는다.
코드
다음과 같이 넣어주면 된다.
return jpaQueryFactory
.select(Projections.constructor(XXXDto.class,
Expressions.as(Expressions.dateTemplate(Date.class, "function('current_date')"), "약어"),
Expressions.as(Expressions.asNumber(0).intValue(), "약어"),
Expressions.as(Expressions.asString("-"), "약어"),
... 중략
해석 & 배울점
1. Select 구문에는 Expressions로 내장함수, 상수값을 적을 수 있고, Expressions.as( 또 다른 Expressions, "약어") 형태로 Expressions.as로 감싸야한다.
왜냐하면 '또 다른 Expressions'의 결과가 Expressions 타입이 아닐 수 있기 때문이다. 상세한 내용은 참조 1(향로님 블로그).
참조1에서는 Expressions.constant로 상수값을 적는 법도 알 수 있었다.
2. 날짜값을 적고 싶다면 dateTemplate을 사용하고, 타입은 Date, Time을 사용한다.
(TODO) LocalDate, LocalDateTime을 해보고 싶었는데 잘 안됐다.. 이런 타입들로 지정하면, console창에 결과는 제대로 나오는데 argument mismatch .... , 라는 에러가 발생한다.
querydsl에서 사용하는 기본 Date, Time 클래스만 지원하는 것 같다는 생각도 들었다..잘 모르겠어서 Dto의 필드의 타입을 Date로 처리했다...
3. DB는 TimeStamp 타입으로 날짜값을 반환할 수 있다.
Date, Time과는 다른 타입으로 TimeStamp 타입을 반환할 수 있다. hibernate 결과 화면에서 혹시 [DATE] 같은 타입이 아니라 [TIMESTAMP] 타입인지 확인해봐야한다.
4. SQL function을 복습했다.
hibernate가 지원하는 SQL function은 이전 글(https://whitepro.tistory.com/453) 에서 학습했었다. 다만 이번에는 SQL Server의 SQL function을 보기 위해서 AbstractTransactSQLDialect 파일을 보게 되었다. 그중에 'current_date' 함수를 찾아서 위 쿼리문과 같이 활용할 수 있었다.
public class SQLServerDialect extends AbstractTransactSQLDialect {
private static final int PARAM_LIST_SIZE_LIMIT = 2100;
private final LimitHandler limitHandler;
... 중략
-> AbstractTransactSQLDialect 파일
abstract class AbstractTransactSQLDialect extends Dialect {
public AbstractTransactSQLDialect() {
...중략
this.registerFunction("ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER));
this.registerFunction("char", new StandardSQLFunction("char", StandardBasicTypes.CHARACTER));
this.registerFunction("len", new StandardSQLFunction("len", StandardBasicTypes.LONG));
this.registerFunction("lower", new StandardSQLFunction("lower"));
this.registerFunction("upper", new StandardSQLFunction("upper"));
this.registerFunction("str", new StandardSQLFunction("str", StandardBasicTypes.STRING));
this.registerFunction("ltrim", new StandardSQLFunction("ltrim"));
this.registerFunction("rtrim", new StandardSQLFunction("rtrim"));
this.registerFunction("reverse", new StandardSQLFunction("reverse"));
... 많은 SQL Server DB 내장함수 function
this.registerFunction("current_timestamp", new NoArgSQLFunction("getdate", StandardBasicTypes.TIMESTAMP));
this.registerFunction("current_time", new NoArgSQLFunction("getdate", StandardBasicTypes.TIME));
this.registerFunction("current_date", new NoArgSQLFunction("getdate", StandardBasicTypes.DATE));
this.registerFunction("getdate", new NoArgSQLFunction("getdate", StandardBasicTypes.TIMESTAMP));
this.registerFunction("getutcdate", new NoArgSQLFunction("getutcdate", StandardBasicTypes.TIMESTAMP));
this.registerFunction("day", new StandardSQLFunction("day", StandardBasicTypes.INTEGER));
this.registerFunction("month", new StandardSQLFunction("month", StandardBasicTypes.INTEGER));
this.registerFunction("year", new StandardSQLFunction("year", StandardBasicTypes.INTEGER));
this.registerFunction("datename", new StandardSQLFunction("datename", StandardBasicTypes.STRING));
...중략
}
참조
1. 기억보단 기록을(향로님) 블로그
'Programming-[Backend] > JPA' 카테고리의 다른 글
[TIL] JPA @ManyToMany 적용, 테이블 이름과 컬럼, 저장 처리 방식 (0) | 2023.05.19 |
---|---|
[링크] could not initialize proxy - no Session (0) | 2023.05.02 |
[링크] JPA Map 결과 리턴(결과 집합 그루핑) (0) | 2022.02.21 |
[TIL][에러] SQL-Server - hibernate; JPA 적용 Sort, Paging 시 데이터 누락, 중복 문제 (0) | 2021.12.18 |
[Querydsl][작성중] 6. 실무 활용 - 사용자 정의 Repository (0) | 2021.12.09 |