Pregunta

Quiero realizar operaciones de tiempo de datos usando HQL hibernate.

Quiero sumar y restar dos fechas, así como restar 1 año o 1 mes de una fecha en particular.

¿Cómo es esto posible usando HQL en hibernación?

¿Fue útil?

Solución

Ver ¿Realizando matemáticas de fecha / hora en HQL? por ejemplo.

Para usar sql personalizado, debe escribir un dialecto de hibernación propio y registrarse:

registerFunction("weekday", 
  new SQLFunctionTemplate(Hibernate.INTEGER, "to_char(?1,'D')") );

Otros consejos

Necesitas crear tu propio dialecto. Algo así como lo siguiente:

public class MyDialect extends MySQLInnoDBDialect{
      public myDialect() {
      super();
      registerFunction("date_add_interval", new SQLFunctionTemplate(Hibernate.DATE, "date_add(?1, INTERVAL ?2 ?3)"));
      }
    }

En Hibernate / MySQL (al menos) Puede convertir ay desde una marca de tiempo Unix. Como la marca de tiempo de Unix es un número entero, puede agregarle un número entero de segundos.

FROM_UNIXTIME(UNIX_TIMESTAMP(date)+ (allowedTimeWindow*86400)) as deadline

Tiene limitaciones, pero es mucho más fácil que los enfoques anteriores.

Este es un problema abierto en Hibernate. A partir de Hibernate 3.3, no existe una forma estándar de manejar las comparaciones de fechas únicamente en HQL:

https://hibernate.atlassian.net/browse/HHH-2434

Hibernate 4.3 ofrece funciones para acceder a Fecha / Hora en HQL que son:

current_timestamp() , current_date() , current_time()

Las operaciones aritméticas pueden ser gestionadas por:

SECOND(...) , MINUTE(...) , HOUR(...) , DAY(...) , MONTH(...) , YEAR(...)

Descargo de responsabilidad: soy un novato en Java

Pude usar current_date() >= fromDate AND dateadd(day, -1, getdate()) <= toDate en una declaración HQL contra un Sybase db en Hibernate 3.5.3, sin registrar ninguna función.

Muestra de uso de enfoque con dialecto para JPA + Hibernate 4.3.1 + MySQL 5

clase pública SampleMySQL5InnoDBDialect extiende org.hibernate.dialect.MySQL5InnoDBDialect {

public SampleMySQL5InnoDBDialect() {
    super();
    registerFunction("date_sub_days", new SQLFunctionTemplate(StandardBasicTypes.DATE, "date_sub(?1, interval ?2 day)"));
}

luego para su clase con anotación de mapeo:

@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 tiene toDate campo de tipo java.sql.Date y duración campo entero (duración en días) y estamos calculando fromDate = toDate - duración y seleccionando todas las entidades que tienen fromDate o toDate dentro del intervalo [startDate, endDate] .

Hibernate4.3 proporciona funciones nativas para acceder a las fechas / marcas de tiempo y realizar operaciones aritmáticas en ellas

Aquí es el enlace a la documentación de qué expresiones se pueden usar en HQL. Pocos de los cuales estoy mencionando: Para acceder a la fecha / hora:

current_date(), current_time(), and current_timestamp()

Las operaciones aritméticas se pueden hacer siguiendo. Estas funciones toman el tiempo como entrada:

second(...), minute(...), hour(...), day(...), month(...), and year(...)

Uno puede obtener la diferencia absoluta de en HQL por

current_timestamp() - dateInstance

donde dateInstance puede tener definición

@Column(name = "updated_at")
@Temporal(TemporalType.TIMESTAMP)
private java.util.Date updatedAt;

El resultado es en 0.1 segundos. Entonces, para una diferencia absoluta de 1 segundo, la expresión anterior dará el resultado como 10.

Entonces una consulta se vería así:

select t from Table t where (current_timestamp() - updatedAt)>600

Usuarios de Postgres ...

registerFunction("dateadd", new SQLFunctionTemplate(StandardBasicTypes.DATE, "(?1 + INTERVAL ?2)"));

con uso de SQL como:

now() < dateadd(:mydate, '-1 day')
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top