Использование HQL для запроса на дату, игнорируя время в Oracle

У меня есть таблица (в Oracle 9 и выше), где мне нужно найти все записи для данного дня с помощью Hibernate. Записи имеют временные метки (с типом данных "дата" ). У некоторых записей есть время, у других - только дата. Это невозможно изменить, так как это результат других приложений, которые я не могу изменить. В SQL я бы написал что-то в строках

SELECT * FROM table WHERE trim(table.date) = to_date('11.06.2009')

чтобы получить все записи для даты, которую я ищу. Мне было интересно, как я могу заставить Hibernate делать это с помощью HQL. Я знаю, что я могу использовать SQL-запросы в Hibernate, но это кажется менее чистым. Есть ли способ сделать это? Если это возможно, этот способ также должен работать с базами данных без оракула, где timestamp будет типом данных.

Ответы

Ответ 1

Вы можете поместить два ограничения в свой HQL, который указывает больше или равен началу даты, в которую вы ищете, и тот, который указывает меньше, чем на следующий день.

то есть.

table.date >=11.06.2009 AND table.date < 11.07.2009

HQL (а также SQL) также позволяет:

table.date between 11.06.2009 AND 11.07.2009

Имейте в виду, что between всегда включен, что означает как >=, так и <= соответственно.
Подробнее о between здесь: http://www.coding-dude.com/wp/java/hibernate-java/hibernate-hql-between-expression/

Ответ 2

Я думаю, что есть два способа решить эту проблему:

  • Используйте criteria запрос и добавьте SQLRestriction. Ограничение примет форму "trim ({alias}.date) =?". Проблема здесь может заключаться в преобразовании входного параметра в правильный тип в Oracle (или другой СУБД). Вы можете указать необходимый (спящий) тип в качестве параметра, но если он зависит от базы данных, он будет жестко запрограммирован.

  • используйте формулу в вашем сопоставлении спящего режима. Отображением будет:

    <class name="Person">
      <property name="birthDay" formula="trim(birthDay)"/>
    </class>

Теперь вы можете использовать систему ввода Hibernate для сравнения с таким явным объектом:

s.createCriteria(Person.class)
 .add(Restrictions.eq("birthDay", new java.sql.Date(System.currentTimeMillis())))
 .list()

Одна проблема, с которой вы столкнетесь с обоими решениями: функция trim может быть недоступна в базе данных. Решение для этого (например, при тестировании на HSQLDB) заключается в том, чтобы поместить import.sql в свой тест на класс (это будет автоматически вызвано Hibernate) и создать там процедуру или функцию. Вы также можете Alter table Person add column birthDay timestamp в этом файле, чтобы сгенерированная схема работала.

Ответ 3

Для CustomHQL вы можете попробовать trunc

Для Ex:

SELECT T0.FirstName as FirstName ,T0.LastLoginDate as LastLoginDate  FROM User T0
WHERE (trunc(T0.LastLoginDate) >= :LastLoginDate) ORDER BY T0.LastLoginDate 

ПРИМЕЧАНИЕ: Где :LastLoginDate - параметр.

Это трюк для меня.

Ответ 4

вы можете использовать функцию trunc() для удаления временной части в столбце DATE.

например: select * from emp where trunc(emp_date) < trunc(current_date()-30)

извлекает все данные о сотрудниках, которые были наняты за 1 месяц до