Я хочу выполнять операции времени данных с использованием hibernate HQL.
Я хочу добавить и вычесть две даты, а также вычесть 1 год или 1 месяц с определенной даты.
Как это возможно, используя HQL в спящем режиме?
Я хочу выполнять операции времени данных с использованием hibernate HQL.
Я хочу добавить и вычесть две даты, а также вычесть 1 год или 1 месяц с определенной даты.
Как это возможно, используя HQL в спящем режиме?
См Выполнение математики даты/времени в HQL? для примера.
Чтобы использовать пользовательский sql, вы должны написать собственный диалоги спящего режима и зарегистрировать:
registerFunction("weekday",
new SQLFunctionTemplate(Hibernate.INTEGER, "to_char(?1,'D')") );
Вам нужно создать свой собственный диалект. Что-то вроде следующего:
public class MyDialect extends MySQLInnoDBDialect{
public myDialect() {
super();
registerFunction("date_add_interval", new SQLFunctionTemplate(Hibernate.DATE, "date_add(?1, INTERVAL ?2 ?3)"));
}
}
Это открытая проблема в Hibernate. Начиная с Hibernate 3.3 нет стандартного способа обработки сравнений даты только в HQL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2434
Hibernate 4.3 предлагает функции доступа к дате/времени в HQL, которые:
current_timestamp() , current_date() , current_time()
Арифметическими операциями могут управлять:
SECOND(...) , MINUTE(...) , HOUR(...) , DAY(...) , MONTH(...) , YEAR(...)
В Hibernate/MySQL (по крайней мере) Вы можете конвертировать в и из отметки времени Unix. Поскольку временная метка unix является целым числом, вы можете добавить к ней целое число секунд.
FROM_UNIXTIME(UNIX_TIMESTAMP(date)+ (allowedTimeWindow*86400)) as deadline
У этого есть ограничения, но это намного легче, чем вышеприведенные подходы.
Отказ от ответственности: я начинаю Java
Я смог использовать current_date() >= fromDate AND dateadd(day, -1, getdate()) <= toDate
в инструкции HQL для базы данных Sybase db в Hibernate 3.5.3 без регистрации каких-либо функций.
Пример использования подхода с диалектом для JPA + Hibernate 4.3.1 + MySQL 5
открытый класс SampleMySQL5InnoDBDialect расширяет org.hibernate.dialect.MySQL5InnoDBDialect {
public SampleMySQL5InnoDBDialect() {
super();
registerFunction("date_sub_days", new SQLFunctionTemplate(StandardBasicTypes.DATE, "date_sub(?1, interval ?2 day)"));
}
то для вашего класса с аннотацией отображения:
@NamedQuery(name = "SampleEntity.getSampleEntitiesForGapOverlapCalculations", query = "from SampleEntity as se where "
+ "((se.toDate between :startDate and :endDate) or (date_sub_days(se.toDate, se.duration) between :startDate and :endDate)) order by se.toDate asc, se.duration desc")
SampleEntity имеет поле toDate типа java.sql.Date и целое число длительность (продолжительность в днях), и мы вычисляем fromDate = toDate - продолжительность и выбор всех объектов с fromDate или toDate внутри интервала [startDate, endDate].. p >
Hibernate4.3 предоставляет собственные функции для доступа к датам/меток времени и для выполнения арифметических операций с ними
Здесь - ссылка на документацию о том, какие выражения могут использоваться в HQL. Немногие из которых я упоминаю: Чтобы получить доступ к дате/времени:
current_date(), current_time(), and current_timestamp()
Арифметические операции можно выполнить следующим образом. Эти функции принимают время как вход:
second(...), minute(...), hour(...), day(...), month(...), and year(...)
Можно получить абсолютную разницу в HQL на
current_timestamp() - dateInstance
где dateInstance может иметь определение
@Column(name = "updated_at")
@Temporal(TemporalType.TIMESTAMP)
private java.util.Date updatedAt;
Результат - через 0,1 секунды. Таким образом, для абсолютной разницы в 1 секунду указанное выше выражение даст результат как 10.
Таким образом, запрос будет выглядеть так:
select t from Table t where (current_timestamp() - updatedAt)>600