QueryDsl Mysql DATE_ADD, ADDDATE
DATA _ADD, ADDDATE Mysql의 Function 사용
시작하기 전에 먼저 이야기 하지면, INTERVAL 이란 예약어 때문에 하이버네이트에서는 사용 할 수가 없다. DATA_ADD 에서 INTERVAL 을 쓰면 구문을 해석 할수 없다고하는 오류를 볼 수 있다.
MYSQL 에서는 ADDDATE라는 것이 있는데 해당 펑션을 이용해서 날짜를 더할때 사용 하도록 한다.
Expressions 사용
표현식을 이용하여 내부 Function을 사용한다.
// DateOperation
Expressions.dateOperation(Date.class, DateTimeOps.ADD_DAYS,qCampaignEntity.endTime,Expressions.asNumber(1));
// DateTemplate DATE_ADD function 사용
Expressions.dateTemplate(Date.class, "DATE_ADD({0}, INTERVAL {1s} day)", qCampaignEntity.endTime, Expressions.constant(1));
// DateTemplate ADDDATE function 사용
Expressions.dateTemplate(Date.class, "ADDDATE({0},{1})", criteriaDate, Expressions.asNumber(-1));
SQLExpressions 사용 - 지원하는 DB만 가능함. (function)
SQLExpressions.addDays(qCampaignEntity.endTime, 1);
SQLExpressions.dateadd(DatePart.day,qCampaignEntity.endTime,1).goe(criteriaDate)
예제
// 기준 날짜 지정
LocalDate localDate = LocalDate.now();
Date criteriaDate = DateUtils.convertStringToDate(localDate.toString(), CalendarPattermn.CALENDER_TYPE_YYYY_MM_DD);
//DateTemplate<Date> date_1 = Expressions.dateTemplate(Date.class, "ADDDATE({0},{1})", qCampaignEntity.endTime, Expressions.asNumber(1));
DateTemplate<Date> date_2 = Expressions.dateTemplate(Date.class, "ADDDATE({0},{1})", criteriaDate, Expressions.asNumber(-1));
whereBuilder
.and(qCampaignEntity.startTime.coalesce(criteriaDate).asDate().loe(criteriaDate)
.and(qCampaignEntity.endTime.coalesce(criteriaDate).asDate().goe(date_2))
);
하이버네이트 다이렉트 사용자 변경
또다른 방법으로 MySQL57Dialect 를 상속받아 커스텀으로 만든후 사용하면 된다고 하는데, 사용방법을 잘몰라서 그런지 테스트에는 실패 했다.
Custom Mysql5dialect
public class ExtendedMySQL5Dialect extends MySQL57Dialect {
public ExtendedMySQL5Dialect() {
super();
registerFunction("date_sub_interval", new SQLFunctionTemplate(DateType.INSTANCE, "date_sub(?1, INTERVAL ?2 ?3)"));
registerFunction("date_add_interval", new SQLFunctionTemplate(DateType.INSTANCE, "date_add(?1, INTERVAL ?2 ?3)"));
}
}
yml 에서 database-platform, hibernate.dialect 에 커스텀한 클레스로 변경 한다.
spring:
jpa:
generate-ddl: true
open-in-view: true
show-sql: false
hibernate:
ddl-auto: validate
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
database: mysql
database-platform: com.aereport.core.crawler.common.repository.ExtendedMySQL5Dialect
properties:
hibernate.dialect: com.aereport.core.crawler.common.repository.ExtendedMySQL5Dialect
hibernate.jdbc.batch_size: 50
hibernate.jdbc.batch_versioned_data: true
hibernate.order_inserts: true
hibernate.order_updates: true
hibernate.enable_lazy_load_no_trans: true
hibernate.format_sql: true
data:
jpa:
repositories:
enabled: true
결론
Expressions 을 사용하고, dateTemplate 의 mysql Function ADDDATE 를 사용한다.
mysql date function 참고
MySQL :: MySQL 8.0 Reference Manual :: 12.6 Date and Time Functions
MySQL :: MySQL 8.0 Reference Manual :: 12.6 Date and Time Functions
12.6 Date and Time Functions This section describes the functions that can be used to manipulate temporal values. See Section 11.2, “Date and Time Data Types”, for a description of the range of values each date and time type has and the valid formats
dev.mysql.com