본문 바로가기
Spring/Spring Data JPA

QueryDsl Mysql DATE_ADD, ADDDATE

by 아이티.파머 2020. 5. 26.
반응형

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 을 사용하고, dateTemplatemysql 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

 

반응형