Table of Contents
QueryDSL 사용하기 – 함수
DB 독립적인 방법
QueryDSL 에서 지원하는 함수인 경우
ANSI 함수의 경우 QueryDSL 에서 지원해 주기에,
바로 함수를 사용할 수 있다.
public List<String> upper() {
System.out.println("DSL Called");
return jpaQueryFactory
.select(user.username.upper().as("username"))
.from(user)
.where(user.username.eq("Lee")).fetch();
}
Projections 의 생성자 패턴 이용
함수의 결과값이 리턴값으로만 쓰이고,
where 조건절에서 사용되지 않는 경우 DTO 생성자에서 변환해 줄 수 있다.
DB 종속적인 방법
QueryDSL 에서 지원하지 않는 함수인데,
또 where 조건절에서 사용되어야 하는 경우,
DB 종속적인 방법이지만 대안이 없으므로 이 방법을 사용한다.
DB 종속적인 방법에도 몇가지 방법이 있는 듯 하지만,
어차피 DB 변경시 추가작업이 필요한 것은 마찬가지이므로,
한가지만 소개합니다.
함수명이 등록된 경우
public List<String> substring() {
return jpaQueryFactory
.select(
Expressions.stringTemplate(
"function('substring', {0}, {1})",
user.email,
Expressions.constant(2))
)
.from(user)
.where(user.username.eq("Lee")).fetch();
}
함수명이 등록되지 않은 경우
함수명이 등록되어 있지 않은 경우 오류가 발생한다.
또, 커스텀 함수(custom function) 을 사용해야 하는 경우도 오류가 발생한다.
@Override
public List<String> left() {
return jpaQueryFactory
.select(
Expressions.stringTemplate(
"function('left', {0}, {1})",
user.email,
Expressions.constant(2))
)
.from(user)
.where(user.username.eq("Lee")).fetch();
}
이럴 땐 Dialect 를 상속 후, 함수명을 등록해 주어야 한다.
public class MyMariadbDialect extends MariaDB103Dialect {
public MyMariadbDialect() {
super();
registerFunction(
"left",
new StandardSQLFunction("left", StandardBasicTypes.STRING)
);
// // Expressions.simpleTemplate(String.class, "사용자정의함수명({0})", user.email)
// registerFunction("사용자정의함수명",
// new SQLFunctionTemplate(
// StandardBasicTypes.STRING,
// "사용자정의함수명(?1)")
// );
// 컬럼 타입 추가
// registerColumnType( Types.TIMESTAMP, "datetime(6)" );
}
}
spring:
jpa:
database-platform: com.example.querydsltest.config.MyMariadbDialect
SqlServer
SqlServer 의 경우 dbo 도 같이 붙여주어야 한다.
public class MySqlServerDialect extends SQLServer2012Dialect {
public MySqlServerDialect() {
super();
registerFunction(
"dbo.getCateCodeFullDepthName",
new StandardSQLFunction("dbo.getCateCodeFullDepthName", StandardBasicTypes.STRING)
);
}
}
Expressions.stringTemplate(
"dbo.getCateCodeFullDepthName({0})",
itemDisplayCategoryItemEntity.id.id).as("categoryFullName")